动态规划 专项

https://leetcode-cn.com/tag/dynamic-programming/problemset/

322. 零钱兑换(中等)

https://leetcode-cn.com/problems/coin-change/

class Solution:
    def coinChange(self, coins: List[int], amount: int) -> int:
        #让dp状态数组的状态数为amount+1,且初始值也为amount + 1
        dp = [amount + 1 for i in range(amount + 1)]
        #base 状态
        dp[0] = 0
        for i in range(len(dp)):
            for coin in coins:
                #子问题无解,跳过
                if i - coin < 0:
                    continue
                dp[i] = min(dp[i],dp[i-coin] + 1)
        return dp[amount] if dp[amount] != amount + 1 else - 1                 

300. 最长递增子序列(中等)

https://leetcode-cn.com/problems/longest-increasing-subsequence/
注意子序列和子串的区别,后者必须连续

class Solution:
    def lengthOfLIS(self, nums: List[int]) -> int:
        #初始化dp数组
        dp = [1 for i  in  range(len(nums))]
        for i in range(len(nums)):
            #寻找最长
            for j in range(i):
                if nums[i] > nums[j]:
                    dp[i] = max(dp[i],dp[j]+1)    
        return max(dp)

5. 最长回文子串(中等)

https://leetcode-cn.com/problems/longest-palindromic-substring/

class Solution:
    def longestPalindrome(self, s: str) -> str:
        n = len(s)
        if n < 2:
            return s
        
        dp = [[False]*n for _ in range(n)]
        for i in range(n): #单个字符肯定是回文字符串
            dp[i][i] = True
        
        start = 0
        maxL = 1
        
        for L in range(2, n + 1): #注意这儿是n+1
            for i in range(n): #左边下标
                j = i + L - 1
                if j >= n:
                    break
                if s[i] != s[j]:
                    dp[i][j] = False
                else:
                    if j - i  < 3:
                        dp[i][j] = True
                    else:
                        dp[i][j] = dp[i+1][j-1]
                if dp[i][j] and L > maxL:
                    start = i
                    maxL = L 
        return s[start:start+maxL]

53. 最大子序和(简单)

#第一次写,可能借助了dp数组
class Solution:
    def maxSubArray(self, nums: List[int]) -> int:
        n = len(nums)
        if n == 0:
            return
        dp = [float('-inf') for i in range(n)]
        dp[0] = nums[0]
        maxSubSeqSum = dp[0]
        for i in range(1,n):
            if dp[i-1] < 0:
                dp[i] = nums[i]
            else:
                dp[i] = dp[i-1] + nums[i]
            if dp[i] > maxSubSeqSum:
                maxSubSeqSum = dp[i]
        return maxSubSeqSum
#第二次写将上面进行优化,因为,其实只用到了前一个状态pre
class Solution:
    def maxSubArray(self, nums: List[int]) -> int:
        pre = 0
        maxSubSeqSum = nums[0]
        for i in range(len(nums)):
            pre = max(nums[i],pre + nums[i])
            maxSubSeqSum = max(pre,maxSubSeqSum)
        return maxSubSeqSum

70. 爬楼梯(简单)

class Solution:
    def climbStairs(self, n: int) -> int:
        if n <= 2:
            return n
        dp = [0 for i in range(n+1)]
        dp[0] = 0
        dp[1] = 1
        dp[2] = 2
        for i in range(3,n + 1):
            dp[i] = dp[i-1] + dp[i-2]
        return dp[n]
#去掉dp数组
class Solution:
    def climbStairs(self, n: int) -> int:
        p1 = 0
        p2 = 1
        for i in range(n):
            p = p1 + p2
            p1 = p2
            p2 = p
        return p

剑指 Offer 13. 机器人的运动范围(中等)

https://leetcode-cn.com/problems/ji-qi-ren-de-yun-dong-fan-wei-lcof/

class Solution:
    def movingCount(self, m: int, n: int, k: int) -> int:
        #数字各个位置求和
        def sumNum(number):
            s = 0
            while number:
                d,r = divmod(number,10)
                number = d
                s += r
            return s
        #判断该位置是否valid
        def flag(i, j, m, n, k):
            if i < 0 or j < 0 or i >= m or j >= n or sumNum(i) + sumNum(j) > k:
                return False 
            else:
                return True
        
        dp = [[False for _ in range(n)] for _ in range(m)]
        global validGrid
        validGrid = 0
        
        def dfs(x, y, m, n, k, dp):
            global validGrid
            offset = [[0,-1],[0,1],[-1,0],[1,0]] #左,右,上,下
            if not flag(x, y, m, n, k) or dp[x][y]:
                return
            else:
                dp[x][y] = True
                validGrid += 1
                for i in range(4):
                    dfs(x + offset[i][0], y + offset[i][1], m, n, k, dp)
        
        dfs(0, 0, m, n, k, dp)       
        return validGrid              

152. 乘积最大子数组(中等)

https://leetcode-cn.com/problems/maximum-product-subarray/

class Solution:
    def maxProduct(self, nums) -> int:
        preMax = 1
        preMin = 1
        maxP = float("-inf")
        for i in range(len(nums)):
            t1 = max(max(preMax * nums[i], nums[i]),nums[i] * preMin)
            t2 = min(min(preMin * nums[i], nums[i]),nums[i] * preMax)
            preMax = t1
            preMin = t2
            #print(preMax,preMin)
            maxP = max(preMax,maxP)
        return maxP

但第一次写的时候,写的代码很丑陋(分类讨论了多种情况,把头都绕晕了,其实可以抽象出来)

class Solution:
    def maxProduct(self, nums) -> int:
        preMax = 1
        preMin = 1
        maxP = nums[0]
        minP = nums[0]
        t1 = 1
        t2 = 1
        for i in range(len(nums)):
            if nums[i] > 0:
                if preMax > 0:
                    t1 = preMax * nums[i]
                    t2 = min(nums[i], preMin * nums[i])
                elif preMax < 0:
                    t1 = nums[i]
                    t2 = preMin * nums[i]
                else:
                    t1 = nums[i]
                    t2 = preMin * nums[i]
            elif  nums[i] < 0:
                if preMax > 0:
                    t1 = max(nums[i], nums[i] * preMin)
                    t2 = min(nums[i], nums[i] * preMax)
                elif preMax < 0:
                    t1 = preMin * nums[i]
                    t2 = nums[i]
                else:
                    t1 = max(0,nums[i]*preMin)
                    t2 = nums[i]
            else:
                t1 = 0
                t2 = 0
            preMax = t1
            preMin = t2
            if preMax > maxP:
                maxP = preMax
        return maxP

55. 跳跃游戏(中等)

https://leetcode-cn.com/problems/jump-game/

class Solution:
    def canJump(self, nums) -> bool:
        maxForward = 0
        for i in range(len(nums)):
            if i + nums[i] > maxForward:
                maxForward = i + nums[i]
            if maxForward <= i:
                break
        return i + 1 >= len(nums)

45. 跳跃游戏 II(中等)

https://leetcode-cn.com/problems/jump-game-ii/

class Solution:
    def jump(self, nums) -> int:
        dp = [float("inf") for i in range(len(nums))]
        dp[0] = 0
        for i in range(1,len(nums)):
            minValue = dp[i]
            for j in range(i):
                if j + nums[j] >= i:
                    minValue = min(minValue, dp[j] + 1)
            dp[i] = minValue
        return dp[len(nums) - 1]

62. 不同路径(中等)

class Solution:
    def uniquePaths(self, m: int, n: int) -> int:
        dp = [[0 for i in range(n + 1)] for j in range(m + 1)]
        dp[1][1] = 1
        for i in range(1,m + 1):
            for j in range(1, n + 1):
               if [i,j] == [1,1]:
                   continue
               dp[i][j] = dp[i - 1][j] + dp[i][j - 1]
        return dp[m][n]

时间复杂度和空间复杂度都是o(m*n)
因此可以用组合的方法,直接计算答案,因为从左上到右下,一共要走m+n-2步,因为只能向右以及向下,所以向右和向下分别走了n-1步和m-1步,因此直接从m+n-2里面挑选出n-1即可

class Solution:
    def uniquePaths(self, m: int, n: int) -> int:
        return math.comb(m + n - 2, n - 1)

这样时间复杂度为o(1)

63. 不同路径 II(中等)

https://leetcode-cn.com/problems/unique-paths-ii/

class Solution:
    def uniquePathsWithObstacles(self, obstacleGrid) -> int:
        m = len(obstacleGrid)
        n = len(obstacleGrid[0])
        dp = [[0 for i in range(n + 1)] for j in range(m + 1)]
        if obstacleGrid[0][0] == 1:
            return 0
        dp[1][1] = 1
        for i in range(1,m + 1):
            for j in range(1, n + 1):
                if [i,j] == [1,1]:
                   continue
                if obstacleGrid[i - 1][j - 1] != 1:
                    dp[i][j] = dp[i - 1][j] + dp[i][j - 1]
        return dp[m][n]

64. 最小路径和(中等)

https://leetcode-cn.com/problems/minimum-path-sum/

class Solution:
    def minPathSum(self, grid) -> int:
        m = len(grid)
        n = len(grid[0])
        dp = [[0 for i in range(n)] for j in range(m)]
        dp[0][0] = grid[0][0]
        for i in range(1, m):
            dp[i][0] = grid[i][0] + dp[i - 1][0]
        for j in range(1, n):
            dp[0][j] = grid[0][j] + dp[0][j - 1]
        for i in range(1, m):
            for j in range(1, n):
                dp[i][j] = min(dp[i - 1][j],dp[i][j - 1]) + grid[i][j]
        return dp[m - 1][n - 1]

22. 括号生成(中等)

https://leetcode-cn.com/problems/generate-parentheses/

class Solution:
    def generateParenthesis(self, n: int):
        s = ""
        pre = [s]
        for i in range(n):
            t = set()
            for valid in pre:
                for j in range(len(valid) + 1):
                    t.add(valid[0:j] + "()" + valid[j:])
            pre = list(t)
        return pre

核心思路是上一次的结果,在其字符串中各个插入"()",靠集合过滤掉重复的valid。

96. 不同的二叉搜索树(中等)

https://leetcode-cn.com/problems/unique-binary-search-trees/

class Solution:
    def numTrees(self, n: int) -> int:
        dp = [0 for i in range(n + 1)]
        dp[0] = 1
        for i in range(1,n + 1):
            s = 0
            for j in range(0, i):
                s += dp[j] * dp[i - j - 1]
            dp[i] = s
        return dp[n]

关键是理解二叉搜索树,求和分别以i做为根结点,左右子树的可能性的乘积

120. 三角形最小路径和(中等)

https://leetcode-cn.com/problems/triangle/

class Solution:
    def minimumTotal(self, triangle) -> int:
        n = len(triangle)
        dp = [[float("inf") for i in range(n + 1)] for j in range(n + 1)]
        dp[0][0] = 0
        for i in range(1,n + 1):
            for j in range(1, i + 1):
                dp[i][j] = min(dp[i - 1][j], dp[i - 1][j - 1]) + triangle[i - 1][j - 1]
        minPathSum = float("inf")
        for j in range(n + 1):
            minPathSum = min(minPathSum,dp[n][j])
        return minPathSum

上面的时间复杂度和空间复杂度都是o(n*n),但是可以根据状态转移方程可以知道的是,下一层的状态只与上一层的状态有关,而不与上面其他层的状态相关,因此可以将空间复杂度控制在o(n)。

import copy
class Solution:
    def minimumTotal(self, triangle) -> int:
        n = len(triangle)
        dp1 = [float("inf") for i in range(n)]
        dp1[0] = 0
        dp2 = [float("inf")  for i in range(n)]
        for i in range(n):
            for j in range(i + 1):
                if j == 0:
                    dp2[j] = dp1[j] + triangle[i][j]
                else:
                    dp2[j] = min(dp1[j],dp1[j - 1]) + triangle[i][j]
            dp1 = copy.copy(dp2) #注意
        minPathSum = min(dp1)
        return minPathSum

上面其实实际用到的空间是2n,按理可以继续优化到n

198. 打家劫舍(中等)

https://leetcode-cn.com/problems/house-robber/

class Solution:
    def rob(self, nums) -> int:
        n = len(nums)
        if n == 1:
            return nums[0]
        dp = [0 for i in range(n + 1)]
        dp[1] = nums[0]
        dp[2] = nums[1]
        for i in range(3,n + 1):
            dp[i] = max(dp[i - 2], dp[i - 3]) + nums[i - 1]
        return max(dp[n],dp[n - 1])

时间复杂度和空间复杂度都是o(N),下面把空间复杂度优化到常数项

class Solution:
    def rob(self, nums) -> int:
        n = len(nums)
        f1 = 0
        f2 = 0
        f3 = 0
        maxSum = 0
        for i in range(n + 2):
            if i >= n:
                money = 0
            else:
                money = nums[i]
            maxSum = max(money + max(f2, f3), maxSum)
            f3 = f2
            f2 = f1
            f1 = maxSum
        return maxSum

221. 最大正方形(中等)

https://leetcode-cn.com/problems/maximal-square/

class Solution:
    def maximalSquare(self, matrix) -> int:
        m = len(matrix)
        n = len(matrix[0])
        dp = [[0 for i in range(n + 1)] for j in range(m + 1)]
        res = 0
        for i in range(1,m + 1):
            for j in range(1, n + 1):
                s = dp[i - 1][j - 1] #左上角正方形边长
                flag = True
                for t in range(1, s + 1):
                    if dp[i][j - t] < 1 or dp[i - t][j] < 1:
                        flag = False
                        break
                if matrix[i - 1][j - 1] == "1": #当前位置是否为1
                    if flag:
                        dp[i][j] = s + 1
                    else:
                        dp[i][j] = t #注意
                else:
                    dp[i][j] = 0
                res = max(res, dp[i][j])
        return res * res

上面其实都了一点弯路,可以直接删繁化简为下面的状态转移方程

class Solution:
    def maximalSquare(self, matrix) -> int:
        m = len(matrix)
        n = len(matrix[0])
        dp = [[0 for i in range(n + 1)] for j in range(m + 1)]
        res = 0
        for i in range(1,m + 1):
            for j in range(1, n + 1):
                if matrix[i - 1][j - 1] == "1": #当前位置是否为1
                    dp[i][j] = min([dp[i - 1][j - 1], dp[i][j -1], dp[i - 1][j]]) + 1
                res = max(res, dp[i][j])
        return res * res

279. 完全平方数(中等)

https://leetcode-cn.com/problems/perfect-squares/

import math
class Solution:
    def numSquares(self, n: int) -> int:
        dp = [float("inf") for i in range(n + 1)]
        dp[0] = 0
        for i in range(1, n + 1):
            minV = float("inf")
            for j in range(1, math.floor(math.sqrt(i)) + 1):
                minV = min(minV, dp[i - j * j] + 1)
            dp[i] = minV
        return dp[n]

算法的时间复杂度为 o ( N ∗ n ) o(N*\sqrt{n}) o(Nn ),空间复杂度为o (N)。

121. 买卖股票的最佳时机(简单)

https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock/

class Solution:
    def maxProfit(self, prices: List[int]) -> int:
        n = len(prices)
        minValue = float(inf)
        maxProfit = float(-inf)
        for i in range(n):
            if prices[i] - minValue > maxProfit:
                maxProfit = prices[i] - minValue
            if prices[i] < minValue:
                minValue = prices[i]
        return maxProfit if maxProfit > 0 else 0

338. 比特位计数(简单)

https://leetcode-cn.com/problems/counting-bits/

class Solution:
    def countBits(self, n: int) -> List[int]:
        dp = [0 for i in range(n + 1)]
        dp[0] = 0
        if n == 0:
            return dp
        preN = 1        
        for i in range(1, n + 1):
            dp[i] = 1 + dp[i - preN] if i / preN != 2 else 1
            if i / preN == 2:
                preN = i
        return dp
#没有用位运算的dp,位运算的解法详见:https://leetcode-cn.com/problems/counting-bits/solution/bi-te-wei-ji-shu-by-leetcode-solution-0t1i/
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: Android专项测试是一种针对Android操作系统进行的测试,旨在评估Android应用程序的质量和性能。在开发Android应用程序之前,进行专项测试可以帮助开发人员发现并解决潜在的问题,以确保应用程序能够在各种设备上稳定运行。 Android专项测试包括以下方面: 1. 兼容性测试:测试应用程序在不同版本的Android操作系统和不同型号的设备上的兼容性。确保应用程序可以在各种设备上按预期运行,不会出现崩溃或错误。 2. 功能测试:测试应用程序的各种功能是否按照设计要求正常运行。包括测试用户界面的交互、各种用户操作的响应和结果等。 3. 性能测试:测试应用程序的性能,包括内存占用、CPU利用率、启动时间、响应时间等。确保应用程序在各种情况下都能够快速响应用户操作,并且在长时间运行时不会导致设备负载过高。 4. 安全性测试:测试应用程序的安全性,包括对数据传输的加密、用户身份验证的安全性等。确保应用程序在处理用户敏感信息时能够保护用户的隐私和安全。 5. 压力测试:对应用程序进行长时间、高负载的测试,以确定其在长时间运行和并发访问时的表现情况。 通过进行Android专项测试,开发人员可以发现并修复潜在的问题,提高应用程序的质量和用户体验。这对于确保应用程序的可靠性、安全性和性能至关重要,也能够增加用户对应用程序的信任度,提高用户的满意度。 ### 回答2: Android专项测试是一种针对Android操作系统进行的测试。Android是一种常用的开源移动操作系统,广泛应用于智能手机、平板电脑等移动设备上。为了确保Android应用程序的质量和稳定性,需要进行专门的测试。 Android专项测试主要包括如下几个方面: 1. 兼容性测试:测试Android应用程序是否能在不同版本的Android操作系统上正常运行。这涉及到测试应用程序在不同分辨率、不同屏幕尺寸的设备上的表现。 2. 功能测试:测试Android应用程序的功能是否按照设计和需求正确运行。这包括对应用程序的各种功能模块进行测试,如用户界面、数据处理、网络交互等。 3. 性能测试:评估Android应用程序的性能,包括运行速度、响应时间、内存占用等。通过性能测试,可以找出应用程序中存在的性能瓶颈,以便优化和改进。 4. 安全测试:检查Android应用程序的安全性,包括用户数据的保护、权限管理等方面。通过安全测试,可以防止应用程序受到黑客攻击或数据泄露等安全问题。 5. 用户体验测试:评估Android应用程序的用户体验,包括界面设计、交互方式、功能布局等。通过用户体验测试,可以提高应用程序的易用性和用户满意度。 综上所述,Android专项测试是为了保证Android应用程序的质量和稳定性而进行的一系列测试。通过兼容性、功能、性能、安全和用户体验等方面的测试,可以发现和解决问题,提升应用程序的质量。 ### 回答3: Android专项测试是一种针对Android操作系统的应用程序进行的测试。Android系统是目前世界上最流行的移动操作系统之一,它在智能手机、平板电脑和其他移动设备中广泛使用。为了确保Android应用程序的质量和稳定性,进行专项测试是至关重要的。 Android专项测试通常包括以下内容: 1. 兼容性测试:测试Android应用程序在不同版本的Android操作系统上的兼容性。由于Android的版本众多,设备的屏幕尺寸、处理器和内存等硬件特性也各异,因此兼容性测试可以确保应用程序在不同环境下正常运行。 2. 功能测试:测试应用程序的各项功能是否按照设计要求正常工作。包括用户界面、数据输入、数据处理、网络通信等方面的功能测试。这可以确保应用程序的各项功能正常,不会出现错误和异常。 3. 性能测试:测试应用程序在不同负载下的性能表现。包括启动时间、响应时间、内存占用和电池消耗等方面的性能测试。这可以评估应用程序的性能是否满足用户的需求,并找出性能瓶颈和优化方向。 4. 安全测试:测试应用程序的安全性。包括数据保护、身份验证、权限管理和代码漏洞等方面的安全测试。这可以确保应用程序不会泄露用户的敏感信息,并能有效防御恶意攻击。 Android专项测试对于开发者和用户来说都是非常重要的。对于开发者来说,通过专项测试可以确保应用程序的质量和稳定性,提高用户体验,增加用户的信任和忠诚度。对于用户来说,专项测试可以提供安全可靠的应用程序,避免因应用程序错误导致的数据丢失和隐私泄露。 总之,Android专项测试是确保Android应用程序质量和稳定性的重要手段,对于开发者和用户来说都是非常有价值的。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

猴猴猪猪

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值