题目:
151. 反转字符串中的单词
给你一个字符串
s
,请你反转字符串中 单词 的顺序。单词 是由非空格字符组成的字符串。
s
中使用至少一个空格将字符串中的 单词 分隔开。返回 单词 顺序颠倒且 单词 之间用单个空格连接的结果字符串。
注意:输入字符串
s
中可能会存在前导空格、尾随空格或者单词间的多个空格。返回的结果字符串中,单词间应当仅用单个空格分隔,且不包含任何额外的空格。示例 1:
输入:s = "the sky is blue
" 输出:"blue is sky the
"示例 2:
输入:s = " hello world " 输出:"world hello" 解释:反转后的字符串中不能存在前导空格和尾随空格。示例 3:
输入:s = "a good example" 输出:"example good a" 解释:如果两个单词间有多余的空格,反转后的字符串需要将单词间的空格减少到仅有一个。提示:
1 <= s.length <= 104
s
包含英文大小写字母、数字和空格' '
s
中 至少存在一个 单词
思路:
1.空间复杂度O(1)的解法:本题的关键在于空格去重,前后和中间都可能有多个空格,可以用快慢指针的方法,fast指针遍历字符串,slow指针从0开始计数,指向要加入的元素的位置,当fast != ' '时,s[slow] = s[fast]; 此处需要注意,除第一个单词前面不加空格外,其他单词中间需要加入空格,此处需单独处理
2.去除空格后的字符串,通过反转两次可以完成单词倒序,第一次全部反转,第二次单词内部反转
算法:
func reverseWords(s string) string {
//快慢指针去除空格
ss := []byte(s)
slow := 0
fmt.Println("~~~~~~初始ss:%s~~~~~", string(ss))
for fast := 0; fast < len(s); fast++ {
if ss[fast] != ' ' {
if slow != 0 {
ss[slow] = ' '
slow++
}
//注意此处为for 不是if
for fast < len(s) && ss[fast] != ' ' { // 复制逻辑
ss[slow] = ss[fast]
slow++
fast++
}
}
}
ss = ss[0:slow]
fmt.Println("去除空格的ss:%s\n,长度为:%d", string(ss), len(ss))
n_s := swap(ss)
fmt.Println("反转n_s:%s\n", string(n_s))
// 翻转每个单词
last := 0
for i := 0; i <= len(n_s); i++ {
//通过i==len(n_s)来处理最后一个单词
if i == len(n_s) || n_s[i] == ' ' {
swap(n_s[last:i])
last = i + 1
}
}
fmt.Println("s:%s", string(n_s))
return string(n_s)
}
//反转单词的方法,单独拎出来
func swap(s []byte) []byte {
i, j := 0, len(s)-1
for i < j {
tmp := s[i]
s[i] = s[j]
s[j] = tmp
i++
j--
}
return s
}
注意:
1.fmt.Println()为调试的debug日志,帮助排查问题
2.基础代码不够熟练,有算法思路也容易写错,需要多次练习
题目:
55. 右旋字符串(第八期模拟笔试)
字符串的右旋转操作是把字符串尾部的若干个字符转移到字符串的前面。给定一个字符串 s 和一个正整数 k,请编写一个函数,将字符串中的后面 k 个字符移到字符串的前面,实现字符串的右旋转操作。
例如,对于输入字符串 "abcdefg" 和整数 2,函数应该将其转换为 "fgabcde"。
输入描述:
输入共包含两行,第一行为一个正整数 k,代表右旋转的位数。第二行为字符串 s,代表需要旋转的字符串。
输出描述:
输出共一行,为进行了右旋转操作后的字符串。
输入&输出示例:
2 abcdefg
fgabcde
提示:
数据范围:
1 <= k < 10000,
1 <= s.length < 10000;
思路:
1.此题与上题类似,可选择反转两次字符串
2.第一次全部反转,第二次分别对[0,k)和[k,len(s)]反转
算法:
package main
import "fmt"
func verse(s []byte, l int ,r int) {
for l < r {
tmp := s[l]
s[l] = s[r]
s[r] = tmp
l++
r--
}
}
func main(){
var k int
var s string
fmt.Scanln(&k)
fmt.Scanln(&s)
ss := []byte(s)
verse(ss,0,len(ss)-1)
verse(ss,0,k-1)
verse(ss,k,len(ss)-1)
fmt.Println(string(ss))
}
注意:
1.注意控制区间左闭右开
题目:
28. 找出字符串中第一个匹配项的下标
给你两个字符串
haystack
和needle
,请你在haystack
字符串中找出needle
字符串的第一个匹配项的下标(下标从 0 开始)。如果needle
不是haystack
的一部分,则返回-1
。示例 1:
输入:haystack = "sadbutsad", needle = "sad" 输出:0 解释:"sad" 在下标 0 和 6 处匹配。 第一个匹配项的下标是 0 ,所以返回 0 。示例 2:
输入:haystack = "leetcode", needle = "leeto" 输出:-1 解释:"leeto" 没有在 "leetcode" 中出现,所以返回 -1 。提示:
1 <= haystack.length, needle.length <= 104
haystack
和needle
仅由小写英文字符组成
思路:
1.暴力解法时间复杂度O(m*n)
2.KMP算法:(周末补)帮你把KMP算法学个通透!(理论篇)_哔哩哔哩_bilibili
算法:
注意
题目:
459. 重复的子字符串
给定一个非空的字符串
s
,检查是否可以通过由它的一个子串重复多次构成。示例 1:
输入: s = "abab" 输出: true 解释: 可由子串 "ab" 重复两次构成。示例 2:
输入: s = "aba" 输出: false示例 3:
输入: s = "abcabcabcabc" 输出: true 解释: 可由子串 "abc" 重复四次构成。 (或子串 "abcabc" 重复两次构成。)提示:
1 <= s.length <= 104
s
由小写英文字母组成
思路:
1.KMP算法的应用,周末补
算法:
注意
总结:
待补充