目录
- 反转专题
- 题目:反转字符串
- 思路分析:左右双指针 + 对向交换
- 复杂度:时间复杂度 O ( n ) O(n) O(n)、空间复杂度 O ( 1 ) O(1) O(1)
- Go代码
- 题目:反转字符串 II
- 思路分析:K个一组反转思想(找到每组的首尾索引)
- 复杂度:时间复杂度 O ( n ) O(n) O(n)、空间复杂度 O ( n ) O(n) O(n)
- Go代码
- 题目:仅仅反转字母
- 思路分析:左右双指针 + 对向交换字母 + 跳过非字母
- 复杂度:时间复杂度 O ( n ) O(n) O(n)、空间复杂度 O ( n ) O(n) O(n)
- Go代码
- 题目:反转字符串中的单词
- 思路分析:去除空格 + 全面反转 + K个一组反转思想(K不定长,找到每组首尾索引)
- 复杂度:时间复杂度 O ( n ) O(n) O(n)、空间复杂度 O ( n ) O(n) O(n)
- Go代码
- 题目:验证回文串
- 思路分析:只留下有效字符后,左右双指针对向比较值
- 复杂度:时间复杂度 O ( n ) O(n) O(n)、空间复杂度 O ( n ) O(n) O(n)
- Go代码
- 题目:字符串中的第一个唯一字符
- 思路分析:使用哈希表存储字符及其出现次数,遍历找到目标字符
- 复杂度:时间复杂度 O ( n ) O(n) O(n)、空间复杂度 O ( n ) O(n) O(n)
- Go代码
- 题目:有效的字母异位词(判断是否互为字符重排)
- 思路分析:使用哈希表存储字符及其出现次数,遍历另一个字符串对哈希表减值,判断是否<0
- 复杂度:时间复杂度 O ( n ) O(n) O(n)、空间复杂度 O ( k ) O(k) O(k)
- Go代码
反转专题
题目:反转字符串
题目链接:LeetCode-344. 反转字符串
思路分析:左右双指针 + 对向交换
复杂度:时间复杂度 O ( n ) O(n) O(n)、空间复杂度 O ( 1 ) O(1) O(1)
Go代码
func reverseString(s []byte) {
length := len(s)
left, right := 0, length-1
for left <= right {
s[left], s[right] = s[right], s[left]
left++
right--
}
return
}
题目:反转字符串 II
题目链接:LeetCode-541. 反转字符串 II
思路分析:K个一组反转思想(找到每组的首尾索引)
复杂度:时间复杂度 O ( n ) O(n) O(n)、空间复杂度 O ( n ) O(n) O(n)
Go代码
func reverseStr(s string, k int) string {
arr := []byte(s)
length := len(arr)
left := 0
for left < length {
// 剩余字符少于 k 个,则将剩余字符全部反转。
if (length-left) < k {
reverse(arr, left, length-1)
} else {
reverse(arr, left, left+k-1)
}
left = left+k*2
}
return string(arr)
}
func reverse(s []byte, left int, right int) {
if left >= right {
return
}
for left<=right {
s[left], s[right] = s[right], s[left]
left++
right--
}
}
题目:仅仅反转字母
题目链接:LeetCode-917. 仅仅反转字母
思路分析:左右双指针 + 对向交换字母 + 跳过非字母
复杂度:时间复杂度 O ( n ) O(n) O(n)、空间复杂度 O ( n ) O(n) O(n)
Go代码
func reverseOnlyLetters(s string) string {
arr := []byte(s)
length := len(arr)
left, right := 0, length-1
for left <= right {
for left <= right && notA2z(arr[left]) {
left++
}
for left <= right && notA2z(arr[right]) {
right--
}
if left <= right {
arr[left], arr[right] = arr[right], arr[left]
left++
right--
}
}
return string(arr)
}
func notA2z (ch byte) bool {
// 大写字母 A - Z 的 ASCII 码范围为 [65,90]
// 小写字母 a - z 的 ASCII 码范围为 [97,122]
if ch < 65 || ch > 122 {
return true
}
if ch > 90 && ch < 97 {
return true
}
return false
}
题目:反转字符串中的单词
题目链接:LeetCode-151. 反转字符串中的单词
思路分析:去除空格 + 全面反转 + K个一组反转思想(K不定长,找到每组首尾索引)
- 去除字符串两端的空格
- 对整个去除空格后的字符串进行了一次反转
- 遍历字符串中的每个单词,将它们进行反转,并拼接成一个新的字符串
与这个图的思路大致相同,不过我们实现是在 翻转每个单词后 加上 一个空格 存储数组中返回。
复杂度:时间复杂度 O ( n ) O(n) O(n)、空间复杂度 O ( n ) O(n) O(n)
Go代码
func reverseWords(s string) string {
arr := []byte(s)
length := len(arr)
left, right := 0, length-1
// 去除首尾空格
for {
if arr[left] == ' ' {
left++
} else {
break
}
}
for {
if arr[right] == ' ' {
right--
} else {
break
}
}
var arr2 []byte
if right < length-1 {
arr2 = arr[left:right+1]
} else {
arr2 = arr[left:]
}
length = len(arr2)
reverse(arr2, 0, length-1)
var arr3 []byte
left = 0
for left < length {
for left < length {
if arr2[left] == ' ' {
left++
} else {
break
}
}
right = left
for right < length {
if arr2[right] == ' ' {
break
} else {
right++
}
}
reverse(arr2, left, right-1)
arr3 = append(arr3, arr2[left:right]...)
if right == length {
break
}
arr3 = append(arr3, ' ')
left = right
}
return string(arr3)
}
func reverse(arr []byte, left int, right int) {
if left >= right {
return
}
for left <= right {
arr[left], arr[right] = arr[right], arr[left]
left++
right--
}
}
题目:验证回文串
题目链接:LeetCode-125. 验证回文串
思路分析:只留下有效字符后,左右双指针对向比较值
复杂度:时间复杂度 O ( n ) O(n) O(n)、空间复杂度 O ( n ) O(n) O(n)
Go代码
func isPalindrome(s string) bool {
arr := []rune{}
for _, v := range s {
if res, ch := isValid(v); res {
arr = append(arr, ch)
}
}
length := len(arr)
left, right := 0, length-1
for left<=right {
if arr[left] != arr[right] {
return false
}
left++
right--
}
return true
}
func isValid(ch rune) (bool, rune) {
if ch >= 'A' && ch <= 'Z' {
ch = ch | 32
return true, ch
}
if ch >= 'a' && ch <= 'z' {
return true, ch
}
if ch >= '0' && ch <= '9' {
return true, ch
}
return false, ch
}
题目:字符串中的第一个唯一字符
题目链接:LeetCode-387. 字符串中的第一个唯一字符
思路分析:使用哈希表存储字符及其出现次数,遍历找到目标字符
复杂度:时间复杂度 O ( n ) O(n) O(n)、空间复杂度 O ( n ) O(n) O(n)
Go代码
func firstUniqChar(s string) int {
maps := make(map[rune]int, 0)
for _, v := range s {
maps[v]++
}
for i, v := range s {
if maps[v] == 1 {
return i
}
}
return -1
}
题目:有效的字母异位词(判断是否互为字符重排)
题目链接:LeetCode-242. 有效的字母异位词
思路分析:使用哈希表存储字符及其出现次数,遍历另一个字符串对哈希表减值,判断是否<0
复杂度:时间复杂度 O ( n ) O(n) O(n)、空间复杂度 O ( k ) O(k) O(k)
- 空间复杂度为 O ( k ) O(k) O(k),其中 k 是字符串中不同字符的数量,即存储在 map 中的键的数量。
Go代码
func isAnagram(s string, t string) bool {
if len(s) != len(t) {
return false
}
maps := getMap(s)
for _, v := range t {
maps[v]--
if maps[v] < 0 {
return false
}
}
return true
}
func getMap(s string) map[rune]int {
ret := make(map[rune]int, 0)
for _, v := range s {
ret[v]++
}
return ret
}