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

46 阅读3分钟

LeetCode 151.翻转字符串里的单词

📖 考察点

1.条件总结

📖 题意理解

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

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

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

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

💡 解题思路

1.先删除前置空格和中间空格,最后删除末尾的空格 2.反转单词,先把整个字符串反转,再把单个单词翻转

思路一:

思路二:

🔑 关键点总结

💻 代码实现

JavaScript

var reverseWords = function (s) {
	const reverse = (arr, l, r) => {
		while (l < r) {
			let temp = arr[l];
			arr[l] = arr[r];
			arr[r] = temp;
			r--, l++;
		}
	};
	const removeSpace = (arr) => {
		let slow = 0;
		let first = 0;
		while (first < arr.length) {
			if (arr[first] === " " && (first === 0 || arr[first - 1] === " ")) {
				first++;
			} else {
				arr[slow++] = arr[first++];
			}
		}
		arr.length = arr[slow - 1] === " " ? slow - 1 : slow;
	};

	const charList = s.split("");
	removeSpace(charList);
	reverse(charList, 0, charList.length - 1);
	let start = 0;
	for (let i = 0; i <= charList.length; i++) {
		if (charList[i] === " " || i === charList.length) {
			reverse(charList, start, i - 1);
			start = i + 1;
		}
	}
	return charList.join("");
};

Rust


⏱️ 复杂度分析

📚 总结与反思


卡码 55.右旋转字符串

📖 考察点

1.数组操作

📖 题意理解

字符串的右旋转操作是把字符串尾部的若干个字符转移到字符串的前面。给定一个字符串 s 和一个正整数 k,请编写一个函数,将字符串中的后面 k 个字符移到字符串的前面,实现字符串的右旋转操作。 

例如,对于输入字符串 "abcdefg" 和整数 2,函数应该将其转换为 "fgabcde"。

💡 解题思路

旋转再旋转

🔑 关键点总结

💻 代码实现

JavaScript

const rightReverseStr = (str,k)=>{
	const charList = str.split("");
	const reverse = (list,l,r)=>{
		while(l<r){
			let temp = list[l];
			list[l] = list[r];
			list[r] = temp;
			l++;
			r--;
		}
	}
	reverse(charList,0,charList.length-1);
	reverse(charList,0,k-1);
	reverse(charList,k,charList.length-1)
	return charList.join("");
}

Rust


⏱️ 复杂度分析

📚 总结与反思


LeetCode 28.找出字符串中第一个匹配项的下标

📖 考察点

kmp算法

📖 题意理解

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

💡 解题思路

kmp算法

🔑 关键点总结

next数组的获取

💻 代码实现

JavaScript

var strStr = function(haystack, needle) {
    const getNext = (str)=>{
        let charList = str.split('');
        let j = 0;
        let next = new Array(charList.length).fill(0);
        for(let i = 1;i<charList.length;i++){
            while(charList[j]!==charList[i] && j>0){
                j = next[j-1];
            };
            if(charList[j]===charList[i]){
                j++;
                next[i]= j;
            }
        }
        return next;
    }
    let nextList = getNext(needle);
    let p = 0;
    for(let i = 0;i<haystack.length;i++){
        while(haystack[i]!==needle[p] && p>0){
            p = nextList[p-1];
        }
        if(haystack[i]===needle[p]){
            if(p===needle.length-1){
                return i - needle.length+1;
            }
            p++;
        }
    }
    return -1;
};

Rust


⏱️ 复杂度分析

📚 总结与反思


LeetCode 459.重复的子字符串

📖 考察点

kmp

📖 题意理解

💡 解题思路

思路一:

思路二:

🔑 关键点总结

💻 代码实现

JavaScript

var repeatedSubstringPattern = function(s) {
    if(s.length === 1){
        return false;
    }

    const getNext=(charList)=>{
        let next = new Array(charList.length).fill(0);
        let j = 0;
        for(let i = 1;i<charList.length;i++){
            while(charList[j]!==charList[i] &&j > 0){
                j = next[j-1];
            }
            if(charList[j]===charList[i]){
                j++;
                next[i] = j
            }
        }
        return next;
    }
    let nextList = getNext(s.split(""));
    
    let countNumber = nextList[nextList.length-1]
    let count0 = nextList.length- countNumber;
    
    if(countNumber===0 || countNumber % count0 !== 0){
        return false;
    }

    return true;
};

Rust


⏱️ 复杂度分析

📚 总结与反思