代码随想录算法训练营第八天| 151.翻转字符串里的单词、卡码网:55.右旋转字符串、28. 实现 strStr()、459.重复的子字符串

151.翻转字符串里的单词

题目:

给你一个字符串 s ,请你反转字符串中单词的顺序。

单词是由非空格字符组成的字符串。s 中使用至少一个空格将字符串中的单词分隔开。

返回单词顺序颠倒且单词之间用单个空格连接的结果字符串。

注意:输入字符串 s中可能会存在前导空格、尾随空格或者单词间的多个空格。返回的结果字符串中,单词间应当仅用单个空格分隔,且不包含任何额外的空格。

思路:

①使用split()方法根据空格分割字符串,使用StringJoiner拼接得到新字符串。

②倒序遍历字符串,找出每个单词,并进行拼接。

代码:

//使用stringjoiner和split()方法
import java.util.*;
class Solution {
    public String reverseWords(String s) {
        StringJoiner sj = new StringJoiner(" ");
        StringBuilder sb = new StringBuilder();
        String[] sArr = s.split(" ");
        for (int i = sArr.length - 1; i >= 0; i--) {
            if (!sArr[i].equals("")) {
                sj.add(sArr[i]);
            }
        }
        return sj.toString();
    }
}
//按字符倒序遍历
class Solution {
    public String reverseWords(String s) {
        char[] sArr = s.toCharArray();
        StringBuilder ans = new StringBuilder();
        // 倒着遍历
        for (int i = sArr.length - 1; i >= 0; i--) {
            // 找到单词的结束位置
            while (i >= 0 && sArr[i] == ' ') {
                --i;
            }
            int end = i;
            if (i < 0) {
                break;
            }
            // 找到单词的起点
            while (i >= 0 && sArr[i] != ' ') {
                --i;
            }
            ans.append(" ").append(s.substring(i + 1, end + 1));
        }
        return ans.toString().trim();
    }
}

卡码网:55.右旋转字符串

题目:

字符串的右旋转操作是把字符串尾部的若干个字符转移到字符串的前面。给定一个字符串 s 和一个正整数 k,请编写一个函数,将字符串中的后面 k 个字符移到字符串的前面,实现字符串的右旋转操作。例如,对于输入字符串 "abcdefg" 和整数 2,函数应该将其转换为 "fgabcde"。

思路:

使用substring()方法截取字符串。

注意参数键盘输入时,不要将第一套体系与第二套体系混用。

代码:

import java.util.*;
class Main{
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String kstr = sc.nextLine();
        int k = Integer.parseInt(kstr);
        String s = sc.nextLine();
        int n = s.length();
        StringBuilder sb = new StringBuilder();
        sb.append(s.substring(n - k));
        sb.append(s.substring(0, n - k));
        System.out.println(sb);
    }
}

28. 实现 strStr()

题目:

给你两个字符串 haystackneedle ,请你在 haystack 字符串中找出 needle 字符串的第一个匹配项的下标(下标从 0 开始)。如果 needle 不是 haystack 的一部分,则返回  -1

  • 1 <= haystack.length, needle.length <= 104
  • haystackneedle 仅由小写英文字符组成

思路:

①使用String的replace()方法,将haystack中的所有needle替换为“0”得到新字符串newStr,遍历newStr,第一个“0”的下标即为第一个匹配项的下标,直接返回。若没有“0”,则说明没有匹配项,返回-1。

②KMP算法。

代码:

//①使用replace()方法
class Solution {
    public int strStr(String haystack, String needle) {
        String newStr = haystack.replace(needle, "0");
        for(int i = 0; i< newStr.length();i++){
            if(newStr.charAt(i)=='0'){
                return i;
            }
        }
        return -1;
    }
}
//KMP算法
class Solution {
    public int strStr(String haystack, String needle) {
        if (needle.length() == 0) {
            return 0;
        }
        int[] next = new int[needle.length()];
        getNext(next, needle);
        int j = 0;
        for (int i = 0; i < haystack.length(); i++) {
            while (j > 0 && needle.charAt(j) != haystack.charAt(i)) {
                j = next[j - 1];
            }
            if (needle.charAt(j) == haystack.charAt(i)) {
                j++;
            }
            if (j == needle.length()) {
                return i - needle.length() + 1;
            }
        }
        return -1;
    }

    private void getNext(int[] next, String s) {
        int j = 0;
        next[0] = 0;
        for (int i = 1; i < s.length(); i++) {
            while (j > 0 && s.chatAt[i] != s.chatAt[j]) {
                j = next[j - 1];
            }
            if (s.chatAt(j) == s.chatAt(i)) {
                j++;
            }
            next[i] = j;
        }
    }
}

459.重复的子字符串

题目:

给定一个非空的字符串 s ,检查是否可以通过由它的一个子串重复多次构成。

字符串 s 仅由小写英文字符组成。

思路:

①移动匹配:当一个字符串s:abcabc,内部由重复的子串组成,那么这个字符串是由前后相同的子串组成。既然前面有相同的子串,后面有相同的子串,用 s + s,这样组成的字符串中,后面的子串做前串,前面的子串做后串,就一定还能组成一个s。

②KMP算法。

代码:

//移动匹配
class Solution {
    public boolean repeatedSubstringPattern(String s) {
        String t = s.substring(1) + s.substring(0, s.length() - 1);
        String r = t.replace(s, "0");
        if (!r.equals(t)) {
            return true;
        }
        return false;
    }
}
//KMP算法
class Solution {
    public int strStr(String haystack, String needle) {
        if (needle.length() == 0) {
            return 0;
        }
        int[] next = new int[needle.length()];
        getNext(next, needle);
        int j = 0;
        for (int i = 0; i < haystack.length(); i++) {
            while (j > 0 && needle.charAt(j) != haystack.charAt(i)) {
                j = next[j - 1];
            }
            if (needle.charAt(j) == haystack.charAt(i)) {
                j++;
            }
            if (j == needle.length()) {
                return i - needle.length() + 1;
            }
        }
        return -1;
    }

    private void getNext(int[] next, String s) {
        int j = 0;
        next[0] = 0;
        for (int i = 1; i < s.length(); i++) {
            while (j > 0 && s.chatAt[i] != s.chatAt[j]) {
                j = next[j - 1];
            }
            if (s.chatAt(j) == s.chatAt(i)) {
                j++;
            }
            next[i] = j;
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值