代码随想录算法训练营第八天

文档讲解:代码随想录 (programmercarl.com)
视频讲解:字符串基础操作! | LeetCode:344.反转字符串_哔哩哔哩_bilibili
状态:

344. 反转字符串 - 力扣(LeetCode) 

简单介绍下这里的^运算符

运算规则
0 ^ 0 = 0
1 ^ 1 = 0
0 ^ 1 = 1
1 ^ 0 = 1 

'a'的补码:01100001
'b'的补码:01100010
'a' ^ 'b' =    00000011
'a' ^ 'b' ^ 'b' = 01100001 = 'a'
'a' ^ 'b' ^ 'a' = 01100010 = 'b'
 

// 时间复杂度O(n)
// 空间复杂度O(1)
class Solution {
    public void reverseString(char[] s) {
        int left = 0;
        int right = s.length - 1;
        while(left < right) {
            s[left] ^= s[right];
            s[right] ^= s[left];
            s[left++] ^= s[right--];
        }
    }
}
// 这个代码中的交换可能更容易理解

// 时间复杂度O(n)
// 空间复杂度O(1)
class Solution {
    public void reverseString(char[] s) {
        int left = 0;
        int right = s.length - 1;
        while(left < right) {
            char temp = s[left];
            s[left++] = s[right];
            s[right--] = temp;
        }
    }
}

541. 反转字符串 II - 力扣(LeetCode)
自己的思路比较乱,直接放示例代码。
 

// 时间复杂度O(n)
// 空间复杂度O(1)
class Solution {
    public String reverseStr(String s, int k) {

        char[] arr = s.toCharArray();

        // length必须先存起来,不然会报错
        int length = arr.length;

        int start = 0;
        while(start < length) {
            int left = start;
            int right = Math.min(start + k - 1, length - 1);
            while(left < right) {
                    arr[left] ^= arr[right];
                    arr[right] ^= arr[left];
                    arr[left++] ^= arr[right--];
            }
            start += (2 * k);
        }
        return new String(arr);
    }
}
// 时间复杂度O(n)
// 空间复杂度O(1)
class Solution {
    public String reverseStr(String s, int k) {

        StringBuffer res = new StringBuffer();

        int length = s.length();
        int start = 0;

        while(start < length) {

            StringBuffer temp = new StringBuffer(); 
            int firstK = Math.min(start + k, length);
            int secondK = Math.min(start + 2 * k, length);

            // 保存start到start + k之间数据反转后的数据
            temp.append(s.substring(start, firstK));
            res.append(temp.reverse());

            // 保存start + k到start + 2 * k之间的数据
            if(firstK < secondK)
                res.append(s.substring(firstK, secondK));

            start += (2 * k);
        }
        return new String(res);
    }
}

 剑指Offer 05.替换空格
由于力扣上没有这题,我把题目复制下来

请实现一个函数,把字符串 s 中的每个空格替换成"%20"。

示例 1: 输入:s = "We are happy."
输出:"We%20are%20happy."

这道题目的可以用双指针的办法来做,作为一个数组填充类问题,在扩充数组后,采用从后向前填充的方式。

public String replaceSpace(String s) {

	if(s == null || s.length == 0)return s;

	StringBuilder spa = new StringBuilder();
	for(int i = 0; i < s.length(); i++) {
		if(s.charAt(i) == " ")spa.append("  ");    // 统计空格的数量并确定要扩充多少
	}

	if(spa.length == 0)return s;

	int fast = s.length - 1;            // 快指针
	s += spa;                           // 扩充
	char[] res = s.toCharArray();
	int slow = res.length - 1;          // 慢指针
	while(fast >= 0) {
		if(res[fast] == ' ') {
			res[slow--] = '0';
			res[slow--] = '2';
			res[slow] = '%';
		} else res[slow] = res[fast];
		fast--;
		slow--;
	}
	return new String(res);
}


151. 反转字符串中的单词 - 力扣(LeetCode)
 

// 巨麻烦的一种写法
class Solution {

    public String reverseWords(String s) {
        StringBuilder str = removeSpace(s);
        reverseAll(str);
        reverseEachWord(str);
        return new String(str);
    }

    // 去掉句中多余的空格
    public StringBuilder removeSpace(String s) {
        StringBuilder str = new StringBuilder();
        int cur = 0;
        int end = s.length();

        // 去掉句首的空格
        while(cur < s.length() && s.charAt(cur) == ' ')cur++;

        // 去掉句末的空格
        while(end > 0 && s.charAt(end - 1) == ' ')end--;

        // 去掉句中多余的空格
        while(cur < end) {
            if (cur != 0 && s.charAt(cur) == s.charAt(cur - 1)
                    && s.charAt(cur) == ' ') {
                cur++;
                continue;
            }
            str.append(s.charAt(cur));
            cur++;
        }
        return str;
    }

    // 将整句左右倒置
    public void reverseAll(StringBuilder str) {
        int left = 0;
        int right = str.length() - 1;
        while(left < right) {
            char temp = str.charAt(left);
            str.setCharAt(left, str.charAt(right));
            str.setCharAt(right, temp);
            left++;
            right--;
        }
    }

    // 将每个单词倒置回来
    public void reverseEachWord(StringBuilder s) {
        int left = 0;
        int end = 0;
        while(end < s.length()) {
            if(s.charAt(end) == ' ' || end == s.length() - 1) {
                int right = end == s.length() - 1 ? end : end - 1;
                while(left < right) {
                    char temp = s.charAt(left);
                    s.setCharAt(left, s.charAt(right));
                    s.setCharAt(right, temp);
                    left++;
                    right--;
                }
                left = end + 1;
            }
            end++;
        }
    }
}
// 简单明白的做法
class Solution {
    public String reverseWords(String s) {
        char[] arr = s.toCharArray();
        char[] res = new char[arr.length + 1];
        int num = 0;
        int i = arr.length - 1;
        while(i >= 0) {
            while(i >= 0 && arr[i] == ' ')i--;
            int right = i;
            while(i >= 0 && arr[i] != ' ')i--;
            for(int j = i + 1; j <= right; j++) {
                res[num++] = arr[j];
                if(j == right)res[num++] = ' ';
            }
        }
        return new String(res, 0, num - 1);
    }
}

剑指Offer58 左旋转字符串

LCR 182. 动态口令 - 力扣(LeetCode):题目比较类似。
 

class Solution {
    public String dynamicPassword(String password, int target) {
        char[] res = password.toCharArray();
        reverse(res, 0, target - 1);
        reverse(res, target, res.length - 1);
        reverse(res, 0, res.length - 1);
        return new String(res);
    }
    public void reverse(char[] password, int start, int end) {
        while(start < end) {
            char temp = password[start];
            password[start++] = password[end];
            password[end--] = temp;
        }
    }
}

心得: 耗时很久,非常痛苦,主要还是倒数第二题

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值