【代码随想录】算法训练计划08

总结:
1、今天的题目以前都写过
2、字符串通用,go喜欢对 []byte 级别进行反转

1、344. 反转字符串

题目:
输入:s = [“h”,“e”,“l”,“l”,“o”]
输出:[“o”,“l”,“l”,“e”,“h”]

思路:
  • 一个反转函数搞定
// 代码一刷-那不就简单的两两交换
func reverseString(s []byte)  {
    s = reverse(s)
}
func reverse(s []byte) []byte {
    leng := len(s)
    for i:=0; i<leng/2; i++ {
        s[i], s[leng-i-1] = s[leng-i-1], s[i]
    }
    return s
}

2、541. 反转字符串 II

题目:
给定一个字符串 s 和一个整数 k,从字符串开头算起,每计数至 2k 个字符,就反转这 2k 字符中的前 k 个字符。
如果剩余字符少于 k 个,则将剩余字符全部反转。
如果剩余字符小于 2k 但大于或等于 k 个,则反转前 k 个字符,其余字符保持原样。
输入:s = “abcdefg”, k = 2
输出:“bacdfeg”

思路:
  • 要如何判断条件,时刻关注剩余字符数量,反转函数是一定不变的
  • 用[]byte接受,最后再转化为string
  • 注意go切片指向的是底层数组,直接[]byte对s 即可,方便操作
func reverseStr(s string, k int) string {
    // 代码一刷
    ss := []byte(s)
    for i:=0; i<len(s); i+=2*k {
        // 条件理解透彻一点,简化一下
        if i+k <= len(s) {
            reverse(ss[i: i+k])
            continue
        } 
        reverse(ss[i:])
    }
    return string(ss)
}
func reverse(s []byte) []byte {
    leng := len(s)
    for i:=0; i<leng/2; i++ {
        s[i], s[leng-i-1] = s[leng-i-1],s[i]
    }
    return s
}





3、LCR 122. 路径加密

题目:
假定一段路径记作字符串 path,其中以 “.” 作为分隔符。现需将路径加密,加密方法为将 path 中的分隔符替换为空格 " ",请返回加密后的字符串。
输入:path = “a.aef.qerf.bb”
输出:“a aef qerf bb”

思路:
  • 这题变过函数名和题意
  • 很简单,直接 for+判断
func pathEncryption(s string) string {
    ss := []byte(s)
    res := make([]byte, 0)
    for i:=0; i<len(s); i++ {
        if ss[i] == '.' {
            res = append(res, []byte("%20")...)
        } else {
            res = append(res, ss[i])
        }
    }
    return string(res)
}


4、151. 反转字符串中的单词

题目:
给你一个字符串 s ,请你反转字符串中 单词 的顺序。
单词 是由非空格字符组成的字符串。s 中使用至少一个空格将字符串中的 单词 分隔开。
返回 单词 顺序颠倒且 单词 之间用单个空格连接的结果字符串。
注意:输入字符串 s中可能会存在前导空格、尾随空格或者单词间的多个空格。返回的结果字符串中,单词间应当仅用单个空格分隔,且不包含任何额外的空格。
输入:s = “the sky is blue”
输出:“blue is sky the”

思路:
  • 注意可能是前后中都有多个空格的,注意处理
  • 注意 i–,每删除一个空格长度减短1
  • 接着使用 strings.Split 即可
  • 反转对字符串级别操作,不需要再对 []byte 级别操作,麻烦
func reverseWords(s string) string {
	// 代码一刷,遇到空格,跳一下,就反转
    // 对一个整个字符串级别的操作,注意 i--,才能用 strings.Split
	for i := 0; i < len(s); i++ {
		if i > 0 && s[i] == ' ' && s[i] == s[i-1] {
			s = s[:i] + s[i+1:]
			i--
		}
	}
	ans := strings.Split(s, " ")
	ans = reverse(ans)
	res := ""
	for _, v := range ans {
		res = res + v
		res = res + " "
	}
	for res[0] == ' ' {
		res = res[1:]
	}
	for res[len(res)-1] == ' ' {
		res = res[:len(res)-1]
	}
	return res
}
func reverse(s []string) []string {
	leng := len(s)
	for i := 0; i < leng/2; i++ {
		s[i], s[leng-i-1] = s[leng-i-1], s[i]
	}
	return s
}

5、LCR 182. 动态口令

题目:
输入: password = “s3cur1tyC0d3”, target = 4
输出: “r1tyC0d3s3cu”
就是前几个字符移动到最后边

思路:
  • 一种方法是,两段分别反转,最后对整个反转就是答案
  • 一种是再声明一个切片,切割操作
func dynamicPassword(s string, n int) string {
    // 不申请新的切片情况下,用反转,三次实现
    ss := []byte(s)
    reverse(ss[:n])
    reverse(ss[n:])
    reverse(ss)
    return string(ss)
    
}
func reverse(s []byte) {
    leng := len(s)
    for i:=0; i<leng/2; i++ {
        s[i], s[leng-i-1] = s[leng-i-1],s[i]
    }
}

你可能感兴趣的:(代码随想录,算法)