507. 完美数-简单
题目描述:
对于一个 正整数,如果它和除了它自身以外的所有 正因子 之和相等,我们称它为 「完美数」。
给定一个 整数 n, 如果是完美数,返回 true;否则返回 false。
题解:
枚举每一个正因子,记录枚举过程的上限防止重复记录,累加起来判断是否等于n,官方答案的数学法直接打表。。。官方给出的范围内一共只有5个数满足条件直接列出来了
代码(Go):
func checkPerfectNumber(num int) bool {
if num == 1{
return false
}
sum := 1
max := num
for i := 2;i < max;i++{
if num%i == 0{
sum += i
max = num/i
sum += 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 := 0
num := 0
m,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 := 0
p := 0
for i := 0;i < k;i++{
p++
sum += code[p]
}
for i := 0;i < l;i++{
re[i] = sum
sum = sum - code[(i + 1)%l] + code[(i + k + 1)%l]
}
}
if k < 0{
sum := 0
p := l
for i := 0;i < -k;i++{
p--
sum += code[p]
}
for i := 0;i < l;i++{
re[i] = sum
sum = 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,1
tempbyte := text[0]
flag := 1
back := 0
for i := 1;i < len(text);i++{
if text[i] == tempbyte{
tempmax++
}else{
if flag == 1{
flag = 0
back = i
}else{
i = back
flag = 1
if dict[rune(tempbyte)] > tempmax{
tempmax++
}
if tempmax > max{
max = tempmax
tempmax = 1
}else{
tempmax = 1
}
tempbyte = text[i]
}
}
}
if dict[rune(tempbyte)] > tempmax{
tempmax++
}
if tempmax > max{
max = tempmax
}
return max
}
总结
今天的中等题是滑动窗口,做的比较顺利,感觉滑动窗口这块问题不大,中等题目前感觉还是回溯和动态规划更难