从零开始的力扣刷题记录-第四十六天

力扣每日四题

  • 507. 完美数-简单
  • 661. 图片平滑器-简单
  • 1652. 拆炸弹-简单
  • 1156. 单字符重复子串的最大长度-中等
  • 总结

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
}

总结

今天的中等题是滑动窗口,做的比较顺利,感觉滑动窗口这块问题不大,中等题目前感觉还是回溯和动态规划更难

你可能感兴趣的:(leetcode刷题,leetcode,算法,golang)