代码随想录-刷题第八天

344. 反转字符串

题目链接:344. 反转字符串

思路:让第一个和最后一个交换位置,第二个和倒数第二个交换位置,依次类推。

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

class Solution {
    public void reverseString(char[] s) {
        // 一左一右两个指针相向而行
        int left = 0, right = s.length - 1;
        while (left < right) {
            // 交换 s[left] 和 s[right]
            char temp = s[left];
            s[left] = s[right];
            s[right] = temp;
            left++;
            right--;
        }
    }

    // public void reverseString(char[] s) {
    //     int len = s.length;
    //     for(int left = 0, right = len - 1; left < right; left++, right--){
    //         char temp = s[left];
    //         s[left] = s[right];
    //         s[right] = temp;
    //     }
    // }
}

这里交换数据的时候也可以通过位运算来交换。

class Solution {
    public void reverseString(char[] s) {
        int l = 0;
        int r = s.length - 1;
        while (l < r) {
            s[l] ^= s[r];  //构造 a ^ b 的结果,并放在 a 中
            s[r] ^= s[l];  //将 a ^ b 这一结果再 ^ b ,存入b中,此时 b = a, a = a ^ b
            s[l] ^= s[r];  //a ^ b 的结果再 ^ a ,存入 a 中,此时 b = a, a = b 完成交换
            l++;
            r--;
        }
    }
}

541. 反转字符串II

题目链接:541. 反转字符串II

思路:反转的思路和反转数组一样,就是交换前面和后面的数据。本题重点要对反转的边界条件进行判断。

时间复杂度O(n)

// 题目的意思其实概括为 每隔2k个反转前k个,尾数不够k个时候全部反转
class Solution {
    public String reverseStr(String s, int k) {
        char[] ch = s.toCharArray();
        for (int i = 0; i < ch.length; i = i + 2 * k) {
            int start = i;
            // 判断尾数够不够k个来取决end指针的位置
            int end = Math.min(ch.length - 1, start + k - 1);
            
            while (start < end) {
                char temp = ch[start];
                ch[start] = ch[end];
                ch[end] = temp;
                start++;
                end--;
            }
        }
        return new String(ch);
    }
}

剑指Offer 05. 替换空格

题目链接:剑指Offer 05. 替换空格

思路:开辟新的空间来进行赋值操作,这样的话实现十分简单。

时间复杂度O(n)

class Solution {
    public String replaceSpace(String s) {
        StringBuffer res = new StringBuffer();
        for (int i = 0; i < s.length(); i++) {
            if (s.charAt(i) == ' ')
                res.append("%20");
            else
                res.append(s.charAt(i));
        }
        return res.toString();
    }
}

151. 翻转字符串里的单词

题目链接:151. 翻转字符串里的单词

思路:使用split()按照空格分割,然后再倒序拼接。

时间复杂度O(n)

class Solution {
    public String reverseWords(String s) {
        String[] strs = s.trim().split(" ");  // 删除首尾空格,分割字符串
        StringBuilder res = new StringBuilder();
        for (int i = strs.length - 1; i >= 0; i--) { // 倒序遍历单词列表
            if (strs[i].equals("")) continue;        // 遇到空单词则跳过
            res.append(strs[i] + " ");    // 将单词拼接至 StringBuilder
        }
        return res.toString().trim(); // 转化为字符串,删除尾部空格,并返回
    }
}

提高本题的难度:不要使用辅助空间,空间复杂度要求为O(1)。


剑指Offer58-II. 左旋转字符串

题目链接:剑指Offer58-II. 左旋转字符串

思路:开辟新的数组,对数组进行赋值操作,同样实现比较简单但意义不大。

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

class Solution {
    public String reverseLeftWords(String s, int n) {
        StringBuffer res = new StringBuffer();
        for(int i = n; i < s.length(); i++){
            res.append(s.charAt(i));
        }
        for(int i = 0; i < n; i++){
            res.append(s.charAt(i));
        }
        return res.toString();
    }
}

更简单做法:

class Solution {
    public String reverseLeftWords(String s, int n) {
        return s.substring(n) + s.substring(0, n);
    }
}

代码随想录上的方法,先对前k个元素进行反转,然后再对后面的元素进行反转,最后对所有元素进行反转,就能够得到目标值。时间复杂度O(n)

class Solution {
    public String reverseLeftWords(String s, int n) {
        StringBuilder sb = new StringBuilder(s);
        reverseString(sb, 0, n - 1);
        reverseString(sb, n, s.length() - 1);
        reverseString(sb, 0, s.length() - 1);
        return sb.toString();
    }
    private void reverseString(StringBuilder s, int start, int end) {
        while (start < end) {
            char temp = s.charAt(start);
            s.setCharAt(start, s.charAt(end));
            s.setCharAt(end, temp);
            start++;
            end--;
        }
    }
}

你可能感兴趣的:(数据结构,数据结构,算法,java,leetcode,字符串)