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

 题目与题解

344.反转字符串

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

代码随想录题解:344.反转字符串

视频讲解:字符串基础操作! | LeetCode:344.反转字符串_哔哩哔哩_bilibili

解题思路:

        字符串就是一个数组,反转就是改变其顺序。方法很简单,设置两个指针,分别从字符串头部和尾部出发向中间走,每次交换一下头尾指针指向的字符,直到两个指针相遇。

class Solution {
    public void reverseString(char[] s) {
		for (int i = 0; i < s.length/2; i++) {
			char temp = s[i];
			s[i] = s[s.length - i - 1];
			s[s.length - i - 1] = temp;
		}
    }
}

看完代码随想录之后的想法 

        while循环更好理解一点,^方式交换看不懂,不学了。

遇到的困难

        无

541. 反转字符串II

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

代码随想录题解:​​​​​​​541. 反转字符串II

视频讲解:字符串操作进阶! | LeetCode:541. 反转字符串II_哔哩哔哩_bilibili

解题思路:

        与反转字符串类似,但是加上了限制条件。可以用每2k个数作为一个数组单位,交换前k个数的值。

    public String reverseStr(String s, int k) {
		char[] string = s.toCharArray();
		for (int i = 0; i < string.length; i = i + 2*k) {
			int charLeft = string.length - i;
			if (charLeft >= k) {
				for (int j = i, m = 1; j < i + k/2; j++, m++) {
					char temp = string[j];
					string[j] = string[i+k-m];
					string[i+k-m] = temp;
				}
			} else {
				for (int j = i, m = 1; j < i + charLeft/2; j++, m++) {
					char temp = string[j];
					string[j] = string[string.length - m];
					string[string.length - m] = temp;
				}
			}
		}
		return new String(string);
    }
}

看完代码随想录之后的想法 

        随想录写法更简洁一点,不需要判断写两次for循环,只需找到实际需要交换的数组末尾,即可进行双指针运行交换。

    public String reverseStr(String s, int k) {
		char[] string = s.toCharArray();
		for (int i = 0; i < string.length; i = i + 2*k) {
			int charLeft = string.length - i;
			int end = Math.min(string.length - 1, i + k - 1);
			int begin = i;
			while (begin < end) {
				char temp = string[begin];
				string[begin] = string[end];
				string[end] = temp;
				begin++;
				end--;
			}
		}
		return new String(string);
    }
}

遇到的困难

        由于Java的限制,String类型是不可修改的,因此需要用StringBuilder类型或char[]替换。写的时候,无论是for循环还是while循环,都要注意边界条件的取值是多少,避免多换或少换。

卡码网:54.替换数字

题目链接:​​​​​​​卡码网:54.替换数字

代码随想录题解:​​​​​​​卡码网:54.替换数字

解题思路:

        先用StringBuilder类型替换输入的String,然后遍历其每一个字符元素进行修改。如果元素为数字,则删除该元素后用insert方法插入“number”,并且下一次遍历的指针向后移动6格。

import java.util.*;
public class ID54Kama {
    public static void main (String[] args) {
        /* code */
        Scanner scanner = new Scanner(System.in);
        String string = scanner.nextLine();
        StringBuilder sb = new StringBuilder(string);
        int i = 0;
        while (i < sb.length()) {
            if (sb.charAt(i) >= '0' && sb.charAt(i) <= '9') {
                sb.deleteCharAt(i);
                sb.insert(i, "number");
                i += 6;
            } else {
                i++;
            }
        }
        System.out.println(sb);
    }
}

看完代码随想录之后的想法 

        不同语言会有一些自己的函数,可以方便使用,java的库函数更优秀,可以简化代码。这里的思路采用新建一个StringBuilder类型,根据string里面是否为数字,判断是将当前字符放入sb还是将number放入sb,更简单。

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);
    }
}

        C++的方法利用了resize函数先扩展数组,然后再填充number。

遇到的困难

        已经很久没有自己写过输入输出了,完全忘光。要记住java的输入是用scanner类型接收的,如果输入为字符串则用scanner.nextLine()接收,如果是整数则用scanner.nextInt()接收。

151.翻转字符串里的单词

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

代码随想录题解:​​​​​​​151.翻转字符串里的单词

视频讲解:字符串复杂操作拿捏了! | LeetCode:151.翻转字符串里的单词_哔哩哔哩_bilibili

解题思路:

        一开始想利用java自己的库函数,先用trim去除前后空格,再用split把单词分隔开后,把非空格的单词插入到新的string数组中,然后把每个单词reverse,最后将其拼成字符串输出。只能说,非常繁琐而且时间空间利用率都极低,后来放弃了这个想法。

        稍微看了一眼随想录的思路,要求要原地修改数组,于是我就直接把它当成一个char数组去处理,先去除头尾的空格,再根据之前做过的移除元素的双指针法,去掉多余空格,得到新的数组start和end位置,然后再对其进行操作。

        这题的核心思想是:反转单词,可以先反转整个字符串,再把里面的每个单词再反转一次,非常巧妙。我自己没有想到这个思路,得到提示以后才写下了正确的代码。

class Solution {
    public String reverseWords(String s) {
		char[] ss = s.toCharArray();
		// 去除头尾的空格
		int start = 0, end = ss.length - 1;
		while (ss[start] == ' ') {
			start++;
		}
		while (ss[end] == ' ' && end > start) {
			end--;
		}
		// 去除中间的空格
		int i = start+1, j = start+1;
		while (j <= end) {
			if (ss[j-1] == ' ' && ss[j] == ' ') {
				j++;
			} else {
				ss[i] = ss[j];
				i++;
				j++;
			}
		}
		end = i - 1;

		// 反转单词 - 先反转整个字符串,再反转其中的每个单词
		reverse(ss, start, end);
		i = start;
		j = start;
		while (j <= end) {
			while (ss[j] != ' ' && j < end) {
				j++;
			}
			if (j == end) reverse(ss, i, j);
			else reverse(ss, i, j - 1);
			i = ++j;
		}
		return new String(ss, start, end - start + 1);
    }

	public void reverse(char[] chars, int start, int end) {
		int i = start, j = end;
		while (i < j) {
			char temp = chars[i];
			chars[i] = chars[j];
			chars[j] = temp;
			i++;
			j--;
		}
	}
}

看完代码随想录之后的想法 

        这道题的本质是模拟,操作没有太多困难的地方,但是步骤较多,需要考虑的方方面面也比较多,要用耐心去完成。

        同样随想录的方法更精简,移除多余空格时,采用for循环,也将i++融入到等式中,行数可以更少;在求解反转单词的每个下标时,我写的条件是ss[j] != ' ' && j < end,解答给的是ss[j] != ' ' || j == end,相比我的,就不用再判断一次j是否到end了,直接用reverse(ss, i, j - 1)就可以覆盖两种情况。

遇到的困难

        审题最重要,做题要耐心。记住这题的思路,以后最好再练习几次。

55.右旋转字符串

题目链接:​​​​​​​55.右旋转字符串

代码随想录题解:55.右旋转字符串

解题思路:

        想复杂了,没想通,直接看答案。

看完代码随想录之后的想法 

        同样也是巧妙的利用多次反转解决长度不一的数组元素交换问题,了解了思路就很好写了。

import java.util.*;
public class ID55Kama {
    public static void main (String[] args) {
        /* code */
        Scanner scanner = new Scanner(System.in);
        int k = scanner.nextInt();
        scanner.nextLine();
        String s = scanner.nextLine();
        char[] ss = s.toCharArray();
        reverseString(ss, 0, ss.length - 1);
        reverseString(ss, 0, k - 1);
        reverseString(ss, k, ss.length - 1);
        System.out.println(new String(ss));
    }
    public static void reverseString(char[] chars, int start, int end) {
        int i = start, j = end;
        while (i < j) {
            char temp = chars[i];
            chars[i] = chars[j];
            chars[j] = temp;
            i++;
            j--;
        }
    }
}

遇到的困难

        其实这道题思路几乎跟上一道一样,但是没有这个sense,很难想到方便的方法。下次要记住,碰到这种涉及到花式反转的题,先整体再局部反转是个好方法。

        另外,java的scanner应用还是不熟,碰到这种先输入数字再输入字符串的就有点懵了。百度了一下,才知道可以用多写一条scanner.nextLine()的方法,就可以接收下一行的字符串了。

今日收获

        字符串相关的题多为模拟实际操作的题,相比之下涉及到的数学公式较少,写起来也不会很复杂,但是操作一多,代码量就会上去。关键是要有耐心去一步步想,把每一步落实到代码上。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值