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

892. 三维形体的表面积-简单

题目描述:
给你一个 n * n 的网格 grid ,上面放置着一些 1 x 1 x 1 的正方体。每个值 v = grid[i][j] 表示 v 个正方体叠放在对应单元格 (i, j) 上。
放置好正方体后,任何直接相邻的正方体都会互相粘在一起,形成一些不规则的三维形体。
请你返回最终这些形体的总表面积。
注意:每个形体的底面也需要计入表面积中。

题解:
遍历矩阵,查找每个位置与周围四个位置的高度差,若高于周围则增加高度差,并且若该位置高度不为0最后还要加2

代码(Go):

func surfaceArea(grid [][]int) int {
    re := 0
    for i := 0;i < len(grid);i++{
        for j := 0;j < len(grid[0]);j++{
            if i >= 1 && grid[i][j] > grid[i - 1][j]{
                re += grid[i][j] - grid[i - 1][j]
            }else if i == 0{
                re += grid[i][j]
            }
            if j >= 1 && grid[i][j] > grid[i][j - 1]{
                re += grid[i][j] - grid[i][j - 1]
            }else if j == 0{
                re += grid[i][j]
            }
            if i < len(grid) - 1 && grid[i][j] > grid[i + 1][j]{
                re += grid[i][j] - grid[i + 1][j]
            }else if i == len(grid) - 1{
                re += grid[i][j]
            }
            if j < len(grid[0]) - 1 && grid[i][j] > grid[i][j + 1]{
                re += grid[i][j] - grid[i][j + 1]
            }else if j == len(grid[0]) - 1{
                re += grid[i][j]
            }
            if grid[i][j] != 0{
                re += 2
            }
        }
    }
    return re
}

2243. 计算字符串的数字和-简单

题目描述:
给你一个由若干数字(0 - 9)组成的字符串 s ,和一个整数。
如果 s 的长度大于 k ,则可以执行一轮操作。在一轮操作中,需要完成以下工作:
将 s 拆分 成长度为 k 的若干 连续数字组 ,使得前 k 个字符都分在第一组,接下来的 k 个字符都分在第二组,依此类推。注意,最后一个数字组的长度可以小于 k 。
用表示每个数字组中所有数字之和的字符串来 替换 对应的数字组。例如,“346” 会替换为 “13” ,因为 3 + 4 + 6 = 13 。
合并 所有组以形成一个新字符串。如果新字符串的长度大于 k 则重复第一步。
返回在完成所有轮操作后的 s 。

题解:
按题意模拟整个过程即可

代码(Go)

func digitSum(s string, k int) string {
    temp := s
    for len(temp) > k{
        i := 0
        sce := []string{}
        for i + k < len(temp){
            sce = append(sce,temp[i:i + k])
            i += k
        }
        if i != len(temp){
            sce = append(sce,temp[i:])
        }
        var temps string
        for _,v := range sce{
            num := 0
            for _,b := range v{
                tempnum,_ := strconv.Atoi(string(b))
                num += tempnum
            }
            temps += strconv.Itoa(num)
        }
        temp = temps
    }
    return temp
}

740. 删除并获得点数-中等

题目描述:
给你一个整数数组 nums ,你可以对它进行一些操作。
每次操作中,选择任意一个 nums[i] ,删除它并获得 nums[i] 的点数。之后,你必须删除 所有 等于 nums[i] - 1 和 nums[i] + 1 的元素。
开始你拥有 0 个点数。返回你能通过这些操作获得的最大点数。

题解:
把每个数的和加起来后实际上就变成了最经典的动态规划题打家劫舍,流程完全一样

代码(Go):

func deleteAndEarn(nums []int) int {
    sum := make([]int, 10001)
    for _,v := range nums {
        sum[v] += v
    }
    return rob(sum)
}

func rob(nums []int) int {
    p, q := nums[0], max(nums[0], nums[1])
    for i := 2; i < len(nums); i++ {
        p,q = q, max(p + nums[i],q)
    }
    return q
}

func max(x int, y int) int {
    if x > y {
        return x
    }
    return y
}

221. 最大正方形-中等

题目描述:
在一个由 ‘0’ 和 ‘1’ 组成的二维矩阵内,找到只包含 ‘1’ 的最大正方形,并返回其面积。

题解:
这个题是之前刚开始做动态规划的时候没做出来的,当时看过官方题解了要不然估计现在也不会做。核心思想就是寻找正方形的右下角,它的边长取决于这个点左上角的三个点决定的,以这个点为右下角的正方形最大边长等于左上角三个正方形的最小边长加一

代码(Go):

func maximalSquare(matrix [][]byte) int {
    dp := make([][]int,len(matrix))
    for i := 0;i < len(matrix);i++{
        temp := make([]int,len(matrix[0]))
        dp[i] = temp
    }
    temp := 0
    for i := 0;i < len(matrix);i++{
        for j := 0;j < len(matrix[0]);j++{
            if matrix[i][j] == '0'{
                dp[i][j] = 0
            }else if i > 0 && j > 0 && matrix[i][j] == '1'{
                dp[i][j] = min(dp[i - 1][j],min(dp[i - 1][j - 1],dp[i][j - 1])) + 1
            }else if matrix[i][j] == '1'{
                dp[i][j] = 1
            }
            if temp < dp[i][j]*dp[i][j]{
                temp = dp[i][j]*dp[i][j]
            }
        }
    }
    return temp
}

func min(x int,y int) int {
    if x < y{
        return x
    }
    return y
}

总结

发现一个分类从简单到难刷动态规划的专栏,准备先跟着这个刷一遍,要不然不知道遇到的题都什么级别,中等题之间的差距太大了

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值