代码随想录算法训练营第8天 | 344.反转字符串 ,541. 反转字符串II ,54. 替换数字(卡码网) ,151.翻转字符串里的单词 ,55. 右旋字符串(卡码网)

打基础的时候,不要太迷恋于库函数。

344.反转字符串

题目链接:https://leetcode.cn/problems/reverse-string/description/

思路:双指针

双指针交换首尾字符即可

class Solution {
    public void reverseString(char[] s) {
        int left = 0,right = s.length-1;
        // 双指针
        while(left<right){
            // 交换首尾
            char tmp = s[right];
            s[right] = s[left];
            s[left] = tmp;
            left++;
            right--;
        }
    }
}

时间复杂度 O(n)
空间复杂度 O(1)

541. 反转字符串II

题目连接:https://leetcode.cn/problems/reverse-string-ii/description/

解法:双指针法

这道题目其实也是模拟,实现题目中规定的反转规则就可以了。
题目的意思其实概括为 每隔2k个反转前k个,尾数不够k个时候全部反转。题目的含义要理解,没理解题意的话就不好写。

class Solution {
    public String reverseStr(String s, int k) {
        //题目的意思其实概括为 每隔2k个反转前k个,尾数不够k个时候全部反转
        char[] arr = s.toCharArray();
        for(int i=0;i<s.length();i+=2*k){
            if(s.length()-i<k)
                reverseStr(arr,i,s.length()-1);
            else 
                reverseStr(arr,i,i+k-1);
        }
        return new String(arr);
            
        
    }
    public void reverseStr(char[] ch,int i,int j){
        for(;i<j;i++,j--){
            char tmp = ch[j];
            ch[j] = ch[i];
            ch[i] = tmp;
        }
    }
}

时间复杂度 O(n)
空间复杂度 O(1)

54. 替换数字(卡码网)

题目连接:https://kamacoder.com/problempage.php?pid=1064

解法:双指针法

c++中如果想把这道题目做到极致,就不要只用额外的辅助空间了。
不过使用Java刷题,一定要使用辅助空间,因为Java里的string不能修改。
首先扩充数组到每个数字字符替换成 “number” 之后的大小。
例如 字符串 “a5b” 的长度为3,那么 将 数字字符变成字符串 “number” 之后的字符串为 “anumberb” 长度为 8。
然后从后向前替换数字字符,也就是双指针法,过程如下:i指向新长度的末尾,j指向旧长度的末尾。
很多数组填充类的问题,其做法都是先预先给数组扩容带填充后的大小,然后在从后向前进行操作。
这么做有两个好处:
(1)不用申请新数组。
(2)从后向前填充元素,避免了从前向后填充元素时,每次添加元素都要将添加元素之后的所有元素向后移动的问题。

import java.util.Scanner;

class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        String s = in.nextLine();
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < s.length(); i++) {
            if (Character.isDigit(s.charAt(i))) {
                sb.append("number");
            }else sb.append(s.charAt(i));
        }
        System.out.println(sb);
    }
}

时间复杂度:O(n)
空间复杂度:O(n)

151.翻转字符串里的单词

题目连接:https://leetcode.cn/problems/reverse-words-in-a-string/

解法:双指针法

将整个字符串都反转过来,那么单词的顺序此时就是倒序了,只不过单词本身也倒序了,那么再把单词反转一下,就是我们所要求的。
概括起来,也就是:
(1)移除多余空格
(2)将整个字符串反转
(3)将每个单词反转

举个例子,源字符串为:"the sky is blue "
移除多余空格 : “the sky is blue”
字符串反转:“eulb si yks eht”
单词反转:“blue is sky the”
这样我们就完成了翻转字符串里的单词。

在实现的细节上,单词级别的反转,left跟right都是只遍历了字符串一次,然后reverse反转字符串也是对于每个字符串只处理一次,总体上所有的反转操作加起来也是O(n),而不是O(n^2)

class Solution {
    public String reverseWords(String s) {
        char[] arr = s.toCharArray();
        // 先去掉前导空格 和 尾随的空格
        int left = 0, right = s.length()-1;
        while(s.charAt(left)==' ') left++;
        while(s.charAt(right)==' ') right--;
        StringBuffer sb = new StringBuffer();
        // 去掉单词中间多余的空格
        for(int i=left;i<=right;i++){
            if(s.charAt(i)!=' ' || sb.charAt(sb.length()-1) != ' '){
                sb.append(s.charAt(i));
            }
        }

        StringBuffer reverseSb = sb.reverse(); 
        // 然后现在的话就是把每个单词给反转了
        left = 0; right = 1;
        while(left<sb.length()){
            while(right<sb.length() && reverseSb.charAt(right)!=' ')
                right++;
            // 此时right是空格或者边界,反转前面的字符串
            reverse(reverseSb,left,right-1);
            left = right+1;
            right = left+1;
        }
        return sb.toString();
    }

    public void reverse(StringBuffer s,int left,int right){
          while(left < right){
              char tmp = s.charAt(right);
              s.setCharAt(right,s.charAt(left));
              s.setCharAt(left,tmp);
              left++;
              right--;
          }
    }
    
}

时间复杂度:O(n)
空间复杂度:O(n)

55. 右旋字符串(卡码网)

题目连接:https://kamacoder.com/problempage.php?pid=1065

思路就是 通过 整体倒叙,把两段子串顺序颠倒,两个段子串里的的字符在倒叙一把,负负得正,这样就不影响子串里面字符的顺序了。
或者直接截取,拼起来也可以吧。

代码随想录算法训练营第8天 | 344.反转字符串 ,541. 反转字符串II ,54. 替换数字(卡码网) ,151.翻转字符串里的单词 ,55. 右旋字符串(卡码网)_第1张图片

import java.util.*;

public class Main{
    public static void main (String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = Integer.parseInt(sc.nextLine());
        String s = sc.nextLine();
        StringBuffer ans = new StringBuffer();
        String left = s.substring(0,s.length()-n);
        String right = s.substring(s.length()-n,s.length());
        ans.append(right);
        ans.append(left);
        System.out.println(ans.toString());
    }
}

时间复杂度:O(n)
空间复杂度:O(n)

你可能感兴趣的:(代码随想录算法训练营,算法)