题目描述:
给定一个许可密钥字符串 s,仅由字母、数字字符和破折号组成。字符串由 n 个破折号分成 n + 1 组。你也会得到一个整数 k 。
我们想要重新格式化字符串 s,使每一组包含 k 个字符,除了第一组,它可以比 k 短,但仍然必须包含至少一个字符。此外,两组之间必须插入破折号,并且应该将所有小写字母转换为大写字母。
返回 重新格式化的许可密钥 。
题解:
从后往前遍历,每k个字符添加一个-,遍历完把最后的-去掉,然后反转即可。
代码(Go):
func licenseKeyFormatting(s string, k int) string {
re := []byte{}
flag := 0
for i := len(s)-1; i >= 0; i-- {
if s[i] != '-' {
re = append(re, byte(unicode.ToUpper(rune(s[i]))))
flag++
if flag%k == 0 {
re = append(re, '-')
}
}
}
if len(re) > 0 && re[len(re)-1] == '-' {
re = re[:len(re)-1]
}
for i, n := 0, len(re); i < n/2; i++ {
re[i], re[n-1-i] = re[n-1-i], re[i]
}
return string(re)
}
题目描述:
整数的 数组形式 num 是按照从左到右的顺序表示其数字的数组。
例如,对于 num = 1321 ,数组形式是 [1,3,2,1] 。
给定 num ,整数的 数组形式 ,和整数 k ,返回 整数 num + k 的 数组形式 。
题解:
先从后往前加再倒序排列,然后把k没有加完的部分加进来再倒序回去,即可得到正确答案。官方题解采用新建一个数组的方式可以只倒序一次得到答案,算是空间换时间了
代码(Go):
func addToArrayForm(num []int, k int) []int {
flag := 0
for i := len(num) - 1;i >= 0;i--{
if num[i] + k%10 + flag < 10{
num[i] = num[i] + k%10 + flag
flag = 0
}else{
num[i] = num[i] + k%10 + flag - 10
flag = 1
}
k /= 10
}
reverse(num)
for flag == 1 || k > 0{
if k%10 + flag < 10{
num = append(num,k%10 + flag)
k /= 10
flag = 0
}else{
num = append(num,0)
k /= 10
}
}
reverse(num)
return num
}
func reverse(num []int) {
for i, n := 0, len(num); i < n/2; i++ {
num[i], num[n-1-i] = num[n-1-i], num[i]
}
}
题目描述:
给定一个数字 N,当它满足以下条件的时候返回 true:
原数字旋转 180° 以后可以得到新的数字。
如 0, 1, 6, 8, 9 旋转 180° 以后,得到了新的数字 0, 1, 9, 8, 6 。
2, 3, 4, 5, 7 旋转 180° 后,得到的不是数字。
易混淆数 (confusing number) 在旋转180°以后,可以得到和原来不同的数,且新数字的每一位都是有效的。
题解:
从后往前提取数字,遇到13457直接返回错误,遇到69倒转提取到的数字,然后直接正常倒转数字的过程计算即可,最后比较一下结果和最初的数字是否相同
代码(Go):
func confusingNumber(n int) bool {
temp := n
re := 0
for temp > 0{
num := temp%10
if num == 2 || num == 3 || num == 4 || num == 5 || num == 7{
return false
}else{
if num == 9{
num = 6
}else if num == 6{
num = 9
}
re *= 10
re += num
temp /= 10
}
}
if re == n{
return false
}
return true
}
题目描述:
给定一个不含重复数字的数组 nums ,返回其 所有可能的全排列 。你可以 按任意顺序 返回答案。
题解:
回溯。回溯的通用流程就是判断终止条件,for循环回溯,先选择,再递归,最后回退选择。踩了一个坑是找到一个排列后不能直接添加进答案数组,需要先创建一个空数组,把得到的排列copy过去再把新数组添加进答案数组,如果直接添加进去会导致已经添加进答案数组中的排列会继续随着排列的变化而变化
代码(Go):
func permute(nums []int) [][]int {
re := [][]int{}
var backtrack = func(sce []int){}
backtrack = func(sce []int){
if len(sce) == len(nums){
temp := make([]int, len(sce))
copy(temp, sce)
re = append(re,temp)
return
}
for i := 0;i < len(nums);i++{
if contain(sce,nums[i]){
continue
}else{
sce = append(sce,nums[i])
backtrack(sce)
sce = sce[:len(sce) - 1]
}
}
}
temp := []int{}
backtrack(temp)
return re
}
func contain(nums []int,target int) bool {
for _,v := range nums{
if v == target{
return true
}
}
return false
}
做了一道回溯题,非常顺利,感觉之前完全不懂的回溯写起来没有那么难,推荐一个总结的博客链接: 数据结构和算法-五大常用算法:回溯算法
写的非常好,把回溯的步骤总结的很清楚,回溯题都可以套用标准流程,自己判断一下终止条件之类的问题就可以了,接下来准备趁热打铁多做几道回溯,把回溯彻底搞定