代码随想录二刷之“字符串”~GO

发布于:2025-08-17 ⋅ 阅读:(18) ⋅ 点赞:(0)

1.344. 反转字符串 - 力扣(LeetCode)

func reverseString(s []byte)  {
    left := 0
    right := len(s)-1
    for left <= right{
      s[left],s[right] = s[right],s[left]
      left++
      right--
    }
    return
}

感悟:还是go语法熟练程度的问题,需要注意的是: s[left],s[right] = s[right],s[left]这是go语言交换的常用写法。或者也可以先转换成rune切片 runes := []rune(s),最后再转换回string(runes),因为string的底层是byte

2.541. 反转字符串 II - 力扣(LeetCode)

func reverseStr(s string, k int) string {
  runes := []rune(s)
  n := len(runes)
  for i := 0;i<n;i += 2*k{
    if i+k >= n{
      reverse(runes[i:n])
    }else{
      reverse(runes[i:i+k])
    }
  }
  return string(runes)
}

func reverse(runes []rune){
  i := 0
  j :=len(runes)-1
  for i<= j{
    runes[i],runes[j] = runes[j],runes[i]
    i++
    j--
  }
}

感悟:题目不难,复习了go语言的string可读性,所以如果要操纵字符串,先要改写成rune类型。同时函数传参的时候也体现了切片的灵活性。runes[i:n]

3.54. 替换数字(第八期模拟笔试)

package main
import "fmt"

func main(){
    var strByte []byte
    fmt.Scanln(&strByte)
    for i := 0;i<len(strByte);i++{
        if strByte[i]>='a'&&strByte[i]<='z'{
            continue
        }
        addbyte := []byte{'n','u','m','b','e','r'}
        strByte = append(strByte[:i],append(addbyte[:len(addbyte)],strByte[i+1:]...)...)
        i+=len(addbyte)-1
    }
    fmt.Println(string(strByte))
}

感悟:本道题不难,需要强化的是go语言append的语法,以及...的运用。... (可变参数)本质上是一种 “语法糖”,自动将切片拆解为多个独立元素,适配 append 的可变参数要求。

4.151. 反转字符串中的单词 - 力扣(LeetCode)

func reverseWords(s string) string {
    runes := []rune(s)
    //去除多余空格
    slow,fast:=0,0
    for len(runes) >0 && fast < len(runes) && runes[fast] == ' '{
      fast++
    }//头部
    for ; fast < len(runes) ;fast++{
      if fast -1 >0 && runes[fast-1] == runes[fast] &&runes[fast] == ' '{
        continue
      }
      runes[slow] = runes[fast]
      slow++//伏笔
    }
    //有可能指向空格的下一位
    if runes[slow-1] == ' ' && slow -1 >0{
      runes = runes[:slow-1]
    }else{
      runes = runes[:slow]
    }
    reverse(runes) //翻转整个字符串
    for i := 0; i < len(runes);i++{
      j := i
      for ;j < len(runes)&&runes[j] != ' ';j++{
      }
      reverse(runes[i:j])
      i = j
    } 
    return string(runes)
}

func reverse(b []rune){
  left := 0
  right := len(b) - 1
  for left < right {
    b[left],b[right] = b[right],b[left]
    left++
    right--
  } 
}

感悟:本道题确实忘了,确实不记得了。严重需要三刷!!!总体思路:双指针去空格,fast负责移动,slow负责赋值。好多细节。除此之外,先整体翻转,再按单词逐个翻转。

5.55. 右旋字符串(第八期模拟笔试)

package main
import "fmt"

func main(){
    var target int
    var str string 
    fmt.Scanln(&target)
    fmt.Scanln(&str)
    runes := []rune(str)
    reverse(runes[:len(runes)])
    reverse(runes[0:target])
    reverse(runes[target:len(runes)])
    fmt.Println(string(runes))
}
func reverse(b []rune){
  left := 0
  right := len(b) - 1
  for left < right {
    b[left],b[right] = b[right],b[left]
    left++
    right--
  } 
}

感悟:没有任何难度,三次翻转而已

6.28. 找出字符串中第一个匹配项的下标 - 力扣(LeetCode)

                字符串匹配问题就要想到kmp

方法一:暴力解法就是遍历他们的起始位置

func strStr(haystack string, needle string) int {
   n, m := len(haystack), len(needle)
    // 特殊情况:needle 为空字符串,返回 0(按题目约定)
    if m == 0 {
        return 0
    }
    // 若 haystack 长度小于 needle,直接返回 -1
    if n < m {
        return -1
    }
    
    // 遍历所有可能的起始位置
    for i := 0; i <= n - m; i++ {
        // 检查从 i 开始的子串是否与 needle 匹配
        match := true
        for j := 0; j < m; j++ {
            if haystack[i+j] != needle[j] {
                match = false
                break
            }
        }
        if match {
            return i
        }
    }
    // 未找到匹配
    return -1
}

方法二:KMP

func getNext(next []int,s string){
  j := 0 //最长公共前后缀
  next[0] = j//前缀表数组
  for i := 1;i<len(s);i++{
    for j>0 && s[i] != s[j]{
      j = next[j-1]
    }
    if s[i] == s[j]{
      j++
    }
    next[i] = j
  }
}

func strStr(haystack string, needle string) int {
  n := len(needle)
  if n == 0{
    return 0
  }
  j := 0
  next := make([]int,n)
  getNext(next,needle)
  for i := 0;i<len(haystack);i++{
    for j > 0 && haystack[i] != needle[j]{
      j = next[j-1]//回退到前一位
    }
    if haystack[i] == needle[j]{
      j++
    }
    if j == n{
      return i - j +1
    }
  }
  return -1
}

感悟:kmp生疏了,但是简单复习一遍之后,感觉更好理解了。

7.459. 重复的子字符串 - 力扣(LeetCode)

func repeatedSubstringPattern(s string) bool {
	n := len(s)
	if n == 0 {
		return false
	}
	j := 0
	next := make([]int, n)
	next[0] = j
	for i := 1; i < n; i++ {
		for j > 0 && s[i] != s[j] {
			j = next[j-1]
		}
		if s[i] == s[j] {
			j++
		}
		next[i] = j
	}
	// next[n-1]  最长相同前后缀的长度
	if next[n-1] != 0 && n%(n-next[n-1]) == 0 {
		return true
	}
	return false
}

感悟:kmp的这两个题确实都需要二刷了,第一个是字符串匹配的问题,第二个是字符串中是否出现重复子串。只不过第一个要建立next,然后利用模式串和文本串的不断匹配去解决,j的含义不同。第二个相当于只建立next,然后通过next[n-1]去判断是否是否重复出现。但是最后的那个判断条件要熟能生巧。。。


网站公告

今日签到

点亮在社区的每一天
去签到