代码随想录day7|344反转字符串541反转字符串II151反转字符串单词Offer5替换空格58左旋转字符串|01笔记

131 阅读1分钟
  • 344反转字符串

  • 代码随想录 (programmercarl.com)
  • 第一印象

  • 使用双指针按照头尾调换。
  • 解题代码

  •     func reverseString(s []byte)  {
            l, r := 0, len(s) - 1
            for l < r {
                s[l],s[r] = s[r], s[l]
                l++
                r--
            }
        }
    
  • 541反转字符串II

  • 代码随想录 (programmercarl.com)
  • 第一印象

  • 想法是用指针每遍历2k个元素便反转前k个值,遍历到末尾时再根据情况写判断
  • 讲解观后感

  • 发现可以利用迭代直接使指针向后2k,因为要找的也就是每2 * k 区间的起点,这样写,程序会高效很多。
  • 遇到问题

  • golang中string为只读的类型,使用以下代码reverse时无法实现。
  •     func reverse(string s,int l,int r) string{
            for l < r {
                s[l], s[r] = s[r], s[l]
            }
            return s
        }
    
  • 解决方法是使用字符切片
  • 解题代码

  •     func reverseStr(s string, k int) string {
            ss := []byte(s)
            length := len(s)
            for i := 0; i < length; i += 2 * k {
             // 1. 每隔 2k 个字符的前 k 个字符进行反转
             // 2. 剩余字符小于 2k 但大于或等于 k 个,则反转前 k 个字符
                if i + k <= length {
                    reverse(ss[i:i+k])
                } else {
                    reverse(ss[i:length])
                }
            }
            return string(ss)
        }
        
        func reverse(b []byte) {
            left := 0
            right := len(b) - 1
            for left < right {
                b[left], b[right] = b[right], b[left]
                left++
                right--
            }
        }
    
  • 剑指offer05 替换空格

  • 代码随想录 (programmercarl.com)
  • 第一印象

  • 可以统计空格出现的次数,然后扩展其大小。然后利用双指针遍历进行填充。
  • 讲解观后感

  • c++等语言的string类型需要指定固定的size,从后往前遍历的方式可以省去交换的步骤,对于这类问题十分方便。golang的切片机制不需要提前提供size大小,所以可以直接便利添加。golang中append内...表示拆开切片,再添加
  • 解题代码

  •     // 遍历添加
        func replaceSpace(s string) string {
            str := make([]byte,0)
            len := len(s)
            // spn := 0
            for i:=0;i<len;i++ {
                if s[i] == ' ' {
                    str = append(str,[]byte("%20")...)
                } else {
                    str = append(str,s[i])
                }
            }
        
            return string(str)
        }
        // 原地修改
        func replaceSpace(s string) string {
            b := []byte(s)
            length := len(b)
            spaceCount := 0
            // 计算空格数量
            for _, v := range b {
                if v == ' ' {
                    spaceCount++
                }
            }
            // 扩展原有切片
            resizeCount := spaceCount * 2
            tmp := make([]byte, resizeCount)
            b = append(b, tmp...)
            i := length - 1
            j := len(b) - 1
            for i >= 0 {
                if b[i] != ' ' {
                    b[j] = b[i]
                    i--
                    j--
                } else {
                    b[j] = '0'
                    b[j-1] = '2'
                    b[j-2] = '%'
                    i--
                    j = j - 3
                }
            }
            return string(b)
        }
    
  • 151反转字符串里的单词

  • 代码随想录 (programmercarl.com)
  • 第一印象

  • 方法是先去除前后多余的以及重复的空格,再整体反转字符串,再单独反转每个单词。
  • 讲解观后感

  • 需要特别注意去除空格使用的方法,避免出现使用erase()等复杂度为On的操作。
  • 解题代码

  •     func reverseWords(s string) string {
            str := []byte(s)
            //去除空格
            str = removeSpace(str)
            //反转整个字符串
            reverse(str)
            //3.反转单个单词  i单词开始位置,j单词结束位置
        	i := 0
        	for i < len(str) {
        		j := i
        		for ; j < len(str) && str[j] != ' '; j++ {
        		}
        		reverse(str[i:j])
        		i = j
        		i++
        	}
        	return string(str)
        }
        func reverse(str []byte){
            l := 0
            r := len(str) -1
            for l < r {
                str[l], str[r] = str[r], str[l]
                l++
                r--
            }
            
        }
        func removeSpace(str []byte) []byte {
            slowIndex, fastIndex := 0, 0
            //删除头部冗余空格
        	for len(str) > 0 && fastIndex < len(str) && str[fastIndex] == ' ' {
        		fastIndex++
        	}
             //删除单词间冗余空格
        	for ; fastIndex < len(str); fastIndex++ {
        		if fastIndex-1 > 0 && str[fastIndex-1] == str[fastIndex] && str[fastIndex] == ' ' {
        			continue
        		}
        		str[slowIndex] = str[fastIndex]
        		slowIndex++
        	}
            //删除尾部冗余空格
        	if slowIndex-1 > 0 && str[slowIndex-1] == ' ' {
        		str = str[:slowIndex-1]
        	} else {
        		str = str[:slowIndex]
        	}
            return str
        }
    
  • 剑指Offer58-II.左旋转字符串

  • 代码随想录 (programmercarl.com)
  • 第一印象

  • 所谓左旋转的实现,可以通过反转字符串的操作完成。依次反转开头到n、n到末尾、整个字符串。
  • 解题代码

  •     func reverseLeftWords(s string, n int) string {
            b := []byte(s)
            // 1. 反转前n个字符
            // 2. 反转第n到end字符
            // 3. 反转整个字符
            reverse(b, 0, n-1)
            reverse(b, n, len(b)-1)
            reverse(b, 0, len(b)-1)
            return string(b)
        }
        // 切片是引用传递
        func reverse(b []byte, left, right int){
            for left < right{
                b[left], b[right] = b[right],b[left]
                left++
                right--
            }
        }