首页 > 其他分享 >Leetcode反转字串541/翻转字串的单词151/实现 strStr方法28/重复的子字符串459

Leetcode反转字串541/翻转字串的单词151/实现 strStr方法28/重复的子字符串459

时间:2024-04-10 15:30:48浏览次数:31  
标签:151 459 right String nums 空格 字串 字符串 left

前言

Leetcode541/151/28

一、541题(反转字符串)

题目描述
给定一个字符串 s 和一个整数 k,从字符串开头算起,每计数至 2k 个字符,就反转这 2k 字符中的前 k 个字符。
如果剩余字符少于 k 个,则将剩余字符全部反转。
如果剩余字符小于 2k 但大于或等于 k 个,则反转前 k 个字符,其余字符保持原样。

题解

mine

class Solution {
    public String reverseStr(String s, int k) {
        char[] nums = s.toCharArray();
        int i=nums.length;
        int j=0;
        while(i>=2*k){
            i = i-2*k;
            reverse(nums,j,j+k-1);//反转2*k长度前k个
            j = j+2*k;//下一组的起点数索引
        }
        if(i>k){
            //剩余字符大于k,反转前k
            reverse(nums,j,j+k-1);
        }else{
            reverse(nums,j,j+i-1);
        }
        //return Arrays.toString(nums);//这个是输出nums数组的遍历
        return new String(nums);
    }
    //反转nums数组的[m,n]字符串
    public void reverse(char[] nums,int m, int n){
        int left=m,right=n;
        char tmp;
        while(left<right){
            tmp=nums[left];
            nums[left] = nums[right];
            nums[right] = tmp;
            //每次都掉了这两句
            left++;
            right--;
        }
    }
}

算法思路:写一个反转数组nums的[m,n]区间的字符串的方法reverse()。然后每隔2*k个串调用一次,剩余的串再根据具体情况调用一次reverse()。
易错点

  • 基础错误,每次都忘记写left++和right–。
  • String和char互转(忘记了):
String s;
char[] nums = s.toCharArray();//String转char[]
return new String(nums);//char[]转String

二、151题(翻转字符串里的单词)

题目描述
给定一个字符串,逐个翻转字符串中的每个单词。
示例 1:

输入:s = “the sky is blue”
输出:“blue is sky the”
示例 2:

输入:s = " hello world "
输出:“world hello”
解释:反转后的字符串中不能存在前导空格和尾随空格。
示例 3:

输入:s = “a good example”
输出:“example good a”
解释:如果两个单词间有多余的空格,反转后的字符串需要将单词间的空格减少到仅有一个。

题解1

mine

class Solution {
    public String reverseWords(String s) {
        char[] nums1 = s.toCharArray();
        char[] nums2 = new char[nums1.length];
        int left=0,right=0,k=nums1.length-1;
        while(left<nums1.length){
            //保证left指向单词的第一个字母
            if(nums1[left]==' '){
                left++;
                continue;
            }
            right = left;
            while(right<nums1.length&&nums1[right]!=' '){
                right++;
            }
            //[left,right)是第一个单词,填入到nums2中,长度为j-i
            for(int i=right-1;i>=left;i--){
                nums2[k--] = nums1[i];
            }
            if(right<nums1.length){
                //表示可以前加空格,不会发生数组出位
                nums2[k--] = ' ';
            }
            left = right+1;
        }
        //拷贝数组前闭后开
        left = 0;
        while(nums2[left]=='\u0000'||nums2[left]==' '){
            left++;
        }
        char[] ans = Arrays.copyOfRange(nums2, left, nums2.length);
        return new String(ans);
    }
}

算法思路

  • 用[left,right)来标注一个单词,然后按照(right->left)方向填入新数组的末尾,并附加上一个空格。
  • 处理开头空格:left一定要指向单词的第一个字母,如果是空格,就left++。
  • 处理末尾空格:不用处理,如果最后一个单词末尾有多个空格,left会一直往后移动直至走到nums.length跳出循环。
  • 处理中间多个空格:假设当前找到了一个单词[left,right),此时right指向的要么是nums.length处,要么是空格,所以让left=right+1。然后会开始新的循环,那么就回到了“处理开头空格”,left会一直移动,直至找到新单词的第一个字母。
  • 所以其实,上述三种空格特殊情况,都是靠如下代码解决的:
while(left<nums1.length){
           //保证left指向单词的第一个字母
           if(nums1[left]==' '){
               left++;
               continue;
           }
           .....
}

注意点

  1. 注意看示例,有很多种情况。
  2. 代码实现:是用和nums1等长的数组num2存储的,最后开头部分可能有空,以及多余的一个空格,所以也要处理:
while(nums2[left]=='\u0000'||nums2[left]==' '){
           left++;
}

题解2

在这里插入代码片

三、28题(实现 strStr())

题目描述
实现 strStr() 函数。
给定一个 haystack 字符串和一个 needle 字符串,在 haystack 字符串中找出 needle 字符串出现的第一个位置 (从0开始)。如果不存在,则返回 -1。
示例 1: 输入: haystack = “hello”, needle = “ll” 输出: 2
示例 2: 输入: haystack = “aaaaa”, needle = “bba” 输出: -1

解法1

暴力

class Solution {
    public int strStr(String haystack, String needle) {
        char[] total = haystack.toCharArray();
        int k=needle.length();
        for(int i=0;i<=total.length-k;i++){
            String s = new String(total,i,k);
            if(s.equals(needle)){
                return i;
            }
        }
        return -1;
    }
}

解法2

见KMP算法文章,其实这道题想考察的是KMP算法

四、459题(重复的子字符串)

题目描述
给定一个非空的字符串,判断它是否可以由它的一个子串重复多次构成。给定的字符串只含有小写英文字母,并且长度不超过10000。
示例 1:
输入: “abab”
输出: True
解释: 可由子字符串 “ab” 重复两次构成。

在这里插入代码片

总结

  • 541简单。
  • 替换数字也很简单,如果要原地转换的话,要点就是从后往前转。比如"a1b"变成"a number b",从后往前遍历,遍历到’b’扔到数组最后,遍历到’1’,数组末尾’b’前面加上"number"。但没什么太大必要,直接两个数组顺着填就好了。
  • 151题有点坑,这题要把示例看全。
  • 右旋字符串,即把字符串尾部的若k个字符转移到字符串的前面,如"abcdefg" 和 k=2,函数应该将其转换为 “fgabcde”。思路是“全部反转+部分翻转”,先全部翻转变为"gfedcba",然后把前两个翻转,后五个翻转,就变成答案"fgabcde"。
  • 字符串JAVA版本比C++简化了很多,总觉得意义不是特别大了,C++的字符串可以变化,考点是O(1)空间变化,JAVA开辟新空间有点暴力解法的意思了,稍微难一点可能就是一些细节的处理。
  • 28题KMP算法。

标签:151,459,right,String,nums,空格,字串,字符串,left
From: https://blog.csdn.net/qq_43969379/article/details/137519087

相关文章

  • 洛谷 P1518 [USACO2.4] 两只塔姆沃斯牛 The Tamworth Two
    [USACO2.4]两只塔姆沃斯牛TheTamworthTwo题目描述两只牛逃跑到了森林里。FarmerJohn开始用他的专家技术追捕这两头牛。你的任务是模拟他们的行为(牛和John)。追击在的平面网格内进行。一个格子可以是:一个障碍物,两头牛(它们总在一起),或者FarmerJohn。两头牛和FarmerJohn......
  • 求字符串的连续最长字串
    前言给定一个字符串,求连续字符最长子串,比如aaaacabbbbbbbc,输出七个b。(牛客上看到的面试手撕题,闲着没事实现了一下)#include<iostream>#include<map>#include<algorithm>usingnamespacestd;intmain(){strings;cin>>s;intcount=1;......
  • asm增加磁盘由于Bug19874632导致磁盘块头丢失ORA-15196
    数据库日志,磁盘组突然被dismount掉:TueApr0210:39:152024Errorsinfile/u01/app/oracle/diag/rdbms/orcl/orcl1/trace/orcl1_lgwr_150319.trc:ORA-00345:redologwriteerrorblock222293count1ORA-00312:onlinelog5thread1:'+DB/orcl/onlinelog/group_5.2......
  • USB高品质过流限流保护芯片PW1515,带输入过压与耐高压功能
    在现代电子设备中,对电压和电流的精准控制是至关重要的。为了满足这一需求,我们推出了PW1515前端过电压和过电流保护装置。这款装置能够实时监控输入电压和充电电流,确保它们始终在正常范围内运行,从而有效保护负载。PW1515以其卓越的性能和广泛的应用领域而备受关注。它采用SOT23-5L......
  • P1435 [IOI2000] 回文字串
    题目:链接:https://www.luogu.com.cn/problem/P1435观察到:在里面插入字符不会影响外面的配对所以以dp[i][j]记录字符串s下标从i到j变化到回文串步数,那么递推公式:if(s[i]==s[j])dp[i][j]=dp[i+1][j-1];elsedp[i][j]=min(dp[i+1][j],dp[i][j-1])+1;就是说如果最外面能......
  • 08天【代码随想录算法训练营34期】第四章 字符串part01(● 344.反转字符串 ● 541. 反
    **344.反转字符串**classSolution:defreverseString(self,s:List[str])->None:left=0right=len(s)-1whileleft<right:temp=s[left]s[left]=s[right]s[right]=temp......
  • [AHK2] 不用结束符的热字串
    开始通常,我们使用热字串是这样的:::;btw::bytheway需要使用结束符(;''.等)来触发。但在官方文档中,找到一种方法可以不使用结束符,基于InputHook的方式。原始的例子就不展示了,我们直接入正题--封装后的代码。代码/***@example*;registeractionsbyconstructor......
  • 459. 重复的子字符串c
    voidbuild(int*next,char*s,intn){next[0]=-1;intindex=1,j=-1;while(index<n){if(j==-1||s[index-1]==s[j]){j++;next[index++]=j;}else{j=next[j];}}for(inti=0;......
  • CF1514D-区间(绝对)众数-莫队、随机化、可持久化线段树
    link:https://codeforces.com/contest/1514/problem/D很久以前小号打的场了,当时D题写的莫队,现在重新来看看。题意:给一个序列\([a_1,\dots,a_n]\),有q次询问,每次问:把\([a_l,\dots,a_r]\)划分最少几个不相交子序列,才能使得每个子序列是beautiful的。称一个序列\(a_1,\dots,a_x\)......
  • 459. 重复的子字符串c
    voidbuild(char*s,int*next,intn){next[0]=-1;inti=1,j=-1;while(i<n){if(j==-1||s[j]==s[i-1]){next[i]=j+1;j++;i++;}else{j=next[j];}}for(inti=0;i&l......