代码随想录 day08 第四章 字符串part01

今日任务

●  344.反转字符串

●  541. 反转字符串II

●  卡码网:54.替换数字

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

●  卡码网:55.右旋转字符串

1. 反转字符串

关联 leetcode 454.四数相加II

  • 题解

    • 双指针实现
    func reverseString(s []byte) {
    	head := 0
    	tail := len(s) - 1
    	for head < tail {
    		s[head], s[tail] = s[tail], s[head]
    		head++
    		tail--
    	}
    }
    

2. 反转字符串II

关联 leetcode 541. 反转字符串II

  • Go截至1.21 版本没有内置reverse() 库函数

  • 思路

    • 每次运动固定 2k 个步长
      • 如果当前仍在数组内
        • 翻转前k个元素
      • 翻转最后几个元素
  • 题解

    func reverseStr(s string, k int) string {
    
    	res := []byte(s)
    	//每次走2k个步长,反转前k个元素
    	for i := 0; i < len(s); i += 2 * k {
    		if i+k <= len(s) {
    			reverse(res[i : i+k])
    		} else {
    			reverse(res[i:])
    		}
    	}
    
    	return string(res)
    }
    
    func reverse(s []byte) {
    	head := 0
    	tail := len(s) - 1
    	for head < tail {
    		s[head], s[tail] = s[tail], s[head]
    		head++
    		tail--
    	}
    }
    

3. 替换数字

关联 卡码网:54.替换数字

  • 题目页面 (kamacoder.com)

  • 题解

    • 直接用golang的数组合并特性
    package main
    
    import (
    	"fmt"
    )
    
    func main() {
    
    	var strByte []byte
    
    	fmt.Scanln(&strByte)
    
    	for i := 0; i < len(strByte); i++ {
    
    		// 遇到数字
    		if strByte[i] >= '0' && strByte[i] <= '9' {
    			// 要替换的数组
    			insertElement := []byte{'n', 'u', 'm', 'b', 'e', 'r'}
    			// 后续需要移动的指针步长
    			moveLen := len(insertElement)
    			// 更新数组
    			insertElement = append(insertElement, strByte[i+1:]...)
    			strByte = append(strByte[:i], insertElement...)
    			// 更新数组后移动指针
    			i = i + moveLen - 1
    		}
    	}
    
    	fmt.Println(string(strByte))
    }
    

4. 翻转字符串里的单词

关联 leetcode 151.翻转字符串里的单词

  • 题解
    • 声明额外数组

      func reverseWords(s string) string {
      	srcSlice := strings.Split(strings.TrimSpace(s), " ")
      	dstSlice := make([]string, 0)
      	for i := range srcSlice {
      		if strings.TrimSpace(srcSlice[i]) != "" {
      			dstSlice = append(dstSlice, srcSlice[i])
      		}
      	}
      	slices.Reverse(dstSlice)
      	s = ""
      	for i := range dstSlice {
      		if i <= len(dstSlice)-2 {
      			s += dstSlice[i] + " "
      		} else {
      			s += dstSlice[i]
      		}
      	}
      	return s
      }
      
    • 原地反转

      1. 去除多于空格

        1. 头部的空格、尾部的空格、单词间冗余的空格
      2. 翻转

        1. 反转所有字符
          1. [I am a cat] —> [tac a ma I]
        2. 再翻转单词
          1. [cat a am I] :完成字符串翻转
      3. 题解

        func reverseWords(s string) string {
        	b := []byte(s)
        
        	// 移除多余空格
        	slow := 0
        	for i := 0; i < len(b); i++ {
        		if b[i] != ' ' {
        			if slow != 0 {
        				b[slow] = ' '
        				slow++
        			}
        			for i < len(b) && b[i] != ' ' {
        				b[slow] = b[i]
        				slow++
        				i++
        			}
        		}
        	}
        	b = b[0:slow]
        
        	//翻转整个字符串
        	reverse(b)
        	//翻转每个单词
        	last := 0
        	for i := 0; i <= len(b); i++ {
        		if i == len(b) || b[i] == ' ' {
        			reverse(b[last:i])
        			last = i + 1
        		}
        	}
        
        	return string(b)
        }
        
        // 翻转字符串
        func reverse(b []byte) {
        	left := 0
        	right := len(b) - 1
        	for left < right {
        		b[left], b[right] = b[right], b[left]
        		left++
        		right--
        	}
        }
        

5. 右旋转字符串

关联 卡码网:55.右旋转字符串

  • 思路

    • 先用 带旋转的 长度,分割字符串
    • 整体翻转原字符串
    • 再根据开始的切割翻转每一段字符串
  • 题解

    package main
    
    import "fmt"
    
    func reverse(s []byte) {
    	l, r := 0, len(s)-1
    	for l < r {
    		s[l], s[r] = s[r], s[l]
    		l++
    		r--
    	}
    }
    func main() {
    	var str string
    	var target int
    
    	fmt.Scanln(&target)
    	fmt.Scanln(&str)
    
    	strBytes := []byte(str)
    	reverse(strBytes)
    	reverse(strBytes[0:target])
    	reverse(strBytes[target:])
    	fmt.Println(string(strBytes))
    }
    
    

  • 14
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值