力扣每日四题
- 507. 完美数-简单
- 661. 图片平滑器-简单
- 1652. 拆炸弹-简单
- 1156. 单字符重复子串的最大长度-中等
- 总结
507. 完美数-简单
题目描述:
对于一个 正整数,如果它和除了它自身以外的所有 正因子 之和相等,我们称它为 「完美数」。
给定一个 整数 n, 如果是完美数,返回 true;否则返回 false。
题解:
枚举每一个正因子,记录枚举过程的上限防止重复记录,累加起来判断是否等于n,官方答案的数学法直接打表。。。官方给出的范围内一共只有5个数满足条件直接列出来了
代码(Go):
func checkPerfectNumber(num int) bool {if num == 1{return false}sum := 1max := numfor i := 2;i < max;i++{if num%i == 0{sum += imax = num/isum += max}}if sum == num{return true}return false
}
661. 图片平滑器-简单
题目描述:
图像平滑器 是大小为 3 x 3 的过滤器,用于对图像的每个单元格平滑处理,平滑处理后单元格的值为该单元格的平均灰度。
每个单元格的 平均灰度 定义为:该单元格自身及其周围的 8 个单元格的平均值,结果需向下取整。(即,需要计算蓝色平滑器中 9 个单元格的平均值)。
如果一个单元格周围存在单元格缺失的情况,则计算平均灰度时不考虑缺失的单元格(即,需要计算红色平滑器中 4 个单元格的平均值)。
题解:
直接遍历模拟整个过程,判断每一个单元格周围的值是否存在,存在就加起来计算平均值
代码(Go):
func imageSmoother(img [][]int) [][]int {re := make([][]int,len(img))for i := 0;i < len(img);i++{temp := make([]int,len(img[0]))re[i] = temp}for i := 0;i < len(img);i++{for j := 0;j < len(img[0]);j++{re[i][j] = calculate(i,j,img)}}return re
}func calculate(x int,y int,img [][]int) int{sum := 0num := 0m,n := len(img),len(img[0])if x - 1 >= 0 && y - 1 >= 0{sum = sum + img[x - 1][y - 1] + img[x][y - 1] + img[x - 1][y]num += 3}else if x - 1 >= 0{sum = sum + img[x - 1][y]num++}else if y - 1 >= 0{sum = sum + img[x][y - 1]num++}if x + 1 < m && y + 1 < n{sum = sum + img[x + 1][y + 1] + img[x][y + 1] + img[x + 1][y]num += 3}else if x + 1 < m{sum = sum + img[x + 1][y]num++}else if y + 1 < n{sum = sum + img[x][y + 1]num ++}if x - 1 >= 0 && y + 1 < n{sum += img[x - 1][y + 1]num++}if x + 1 < m && y - 1 >= 0{sum += img[x + 1][y - 1]num++}return (sum + img[x][y])/(num + 1)
}
1652. 拆炸弹-简单
题目描述:
你有一个炸弹需要拆除,时间紧迫!你的情报员会给你一个长度为 n 的 循环 数组 code 以及一个密钥 k 。
为了获得正确的密码,你需要替换掉每一个数字。所有数字会 同时 被替换。
如果 k > 0 ,将第 i 个数字用 接下来 k 个数字之和替换。
如果 k < 0 ,将第 i 个数字用 之前 k 个数字之和替换。
如果 k == 0 ,将第 i 个数字用 0 替换。
由于 code 是循环的, code[n-1] 下一个元素是 code[0] ,且 code[0] 前一个元素是 code[n-1] 。
给你 循环 数组 code 和整数密钥 k ,请你返回解密后的结果来拆除炸弹!
题解:
滑动窗口,每次移动都加入一个元素并且删除最远的元素,思想比较简单。终于见到了久违的双100%击败
代码(Go):
func decrypt(code []int, k int) []int {if k == 0{for i,_ := range code{code[i] = 0}}l := len(code)re := make([]int,l)if k > 0{sum := 0p := 0for i := 0;i < k;i++{p++sum += code[p]}for i := 0;i < l;i++{re[i] = sumsum = sum - code[(i + 1)%l] + code[(i + k + 1)%l]}}if k < 0{sum := 0p := lfor i := 0;i < -k;i++{p--sum += code[p]}for i := 0;i < l;i++{re[i] = sumsum = sum - code[p%l] + code[(p - k)%l]p++}}return re
}
1156. 单字符重复子串的最大长度-中等
题目描述:
如果字符串中的所有字符都相同,那么这个字符串是单字符重复的字符串。
给你一个字符串 text,你只能交换其中两个字符一次或者什么都不做,然后得到一些单字符重复的子串。返回其中最长的子串的长度。
题解;
依然是滑动窗口。用两个变量记录最长子字符串和当前子字符串长度,然后用一个变量记录当前对比的字符,一个变量记录比较失败时回退的位置,还有一个变量用于判断比较失败,失败一次时由于可以调整两个字符的位置所以仍然可以连通,只不过要记录此时的位置方便回退,失败第二次时触发回退,比较记录子字符串长度并且更改当前对比字符。比较特殊的是当字符串中的字符数多于最长子字符串长度时,说明可以换来一个相同的字符使字符串长度加一,所以要先用一个哈希表存储字符串中各字符出现的次数,再比较字符串长度时需要考虑是否需要加一
代码(Go):
func maxRepOpt1(text string) int {dict := map[rune]int{}for _,v := range text{if _,ok := dict[v];ok{dict[v]++}else{dict[v] = 1}}max,tempmax := 1,1tempbyte := text[0]flag := 1back := 0for i := 1;i < len(text);i++{if text[i] == tempbyte{tempmax++}else{if flag == 1{flag = 0back = i}else{i = backflag = 1if dict[rune(tempbyte)] > tempmax{tempmax++}if tempmax > max{max = tempmaxtempmax = 1}else{tempmax = 1}tempbyte = text[i]}}}if dict[rune(tempbyte)] > tempmax{tempmax++}if tempmax > max{max = tempmax}return max
}
总结
今天的中等题是滑动窗口,做的比较顺利,感觉滑动窗口这块问题不大,中等题目前感觉还是回溯和动态规划更难