动态规划思路

参考

状态转移方程:

明确「状态」-> 定义dp数组/函数的含义 -> 明确「选择」-> 明确 base case

试题

53最大子序和

题目描述

53

给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。

示例:

  1. 输入: [-2,1,-3,4,-1,2,1,-5,4],
  2. 输出: 6
  3. 解释: 连续子数组 [4,-1,2,1] 的和最大,为 6

题解思路

思路一

我可以这么想pd[i]表示指针一直扫到i时目前存在的连续区间的最大和。那就不需要记录每个以nums[i]结尾的连续区间最大和,即上面代码注释那里。我们直接取pd[i]不就时我们想要的结果了吗。

指针指到i后的状态:

  • 我们将nums[i]作为连续区间末尾
  • 我们不将nums[i]作为连续区间末尾

由此想到,改变的量不只是i还有是否将nums[i]作为末尾,所以还有一个变量或者我理解成选择,于是pd[i]变成pd[i][0], pd[i][1],其中0代表不将nums[i]作为结尾,1代表将nums[i]作为结尾。

dp[i][0]含义: 到nums[i]为止,不以nums[i]为结尾,前面连续区间和的最大值。dp[i][1]类似。

状态转移方程

  1. dp[i][0] = max(dp[i-1][0], dp[i-1][1]) # 不以nums[i]结尾,那最大的就是前面i-1两种情况中一个
  2. dp[i][1] = max(dp[i-1][1]+nums[i], nums[i]) #以i结尾

base case

  1. dp[0][0] = -inf # 这里不选0结尾,那最大和为什么不是0,是为了防止nums[0]<0,那么dp[1][0] = 0而不是nums[0]出错
  2. dp[0][1] = nums[0]

题解

  1. class Solution:
  2. def maxSubArray(self, nums: List[int]) -> int:
  3. dp = [[0]*2]*len(nums)
  4. dp[0][0] = float("-inf")
  5. dp[0][1] = nums[0]
  6. for i in range(1, len(nums)):
  7. dp[i][0] = max(dp[i-1][0], dp[i-1][1])
  8. dp[i][1] = max(dp[i-1][1]+nums[i], nums[i])
  9. return max(dp[len(nums)-1][0], dp[len(nums)-1][1])

这里其实不需要dp[i][0],因为这道题里,最大情况只会存在于pd[i][1]里(因为假设最大情况以nums[i]结尾,那最大的就是Pd[i][1])。而pd[i][1]与pd[i][0]毫无关系,所以不需要计算pd[i][0],状态转移方程:pd[i] = max(pd[i-1]+nums[1], nums[i]),这里循环的同时,将nums扫过的部分看作pd[i],更新。

  1. class Solution:
  2. def maxSubArray(self, nums: List[int]) -> int:
  3. for i in range(1,len(nums)):
  4. nums[i] = max(nums[i-1]+nums[i], nums[i])
  5. return max(nums)

64最小路径和

题目描述

64

给定一个包含非负整数的 m x n 网格,请找出一条从左上角到右下角的路径,使得路径上的数字总和为最小。

说明:每次只能向下或者向右移动一步。

示例:

  1. 输入:
  2. [
  3.   [1,3,1],
  4. [1,5,1],
  5. [4,2,1]
  6. ]
  7. 输出: 7
  8. 解释: 因为路径 13111 的总和最小。

题目思路

明确状态dp的含义,dp[i][j]:从左上角走到(i,j)处,路劲数字和最小为dp[i][j]

两种选择,右或下,就造成dp[i][j]由下面两种结果得到

状态转移方程:dp[i][j] = min(dp[i-1][j], dp[i][j-1]) + nums[i][j]

base case: 这里的初始化比较复杂点,因为当i或j=0时,在状态转移方程里出现了 i-1=-1,j-1=-1这肯定是不可能的。所以要初始化dp[i][0]以及dp[0][j]

这里的初始化也好初始化,因为dp[i][0]只能是从dp[0][0]一路往下走,dp[0][j]同样从dp[0][0]一路往右走。 带pd数组的迭代法,自下而上,一般递归是自上而下。

题解

  1. # 战胜99.74 %的方法
  2. class Solution:
  3. def minPathSum(self, grid: List[List[int]]) -> int:
  4. m = len(grid)
  5. n = len(grid[0])
  6. dp = [[0 for i in range(n)] for j in range(m)]
  7. dp[0][0] = grid[0][0]
  8. for i in range(1,m):
  9. dp[i][0] = dp[i-1][0] + grid[i][0]
  10. for i in range(1,n):
  11. dp[0][i] = dp[0][i-1] + grid[0][i]
  12. for i in range(1,m):
  13. for j in range(1,n):
  14. dp[i][j] = min(dp[i-1][j], dp[i][j-1]) + grid[i][j]
  15. return dp[m-1][n-1]

这道题遇到的问题

dp = [[0 for i in range(n)] for j in range(m)] 这句话我一开始写的是 dp = [[0]n]m,这样是绝对不行的。因为这种 , 一旦改变一个值所有都变了。比如

  1. a = [[0]*5]*5
  2. a[0][0] = 1
  3. print(a)
  4. 输出:
  5. [[1, 0, 0, 0, 0],
  6. [1, 0, 0, 0, 0],
  7. [1, 0, 0, 0, 0],
  8. [1, 0, 0, 0, 0],
  9. [1, 0, 0, 0, 0]]

所以在pytohn里初始化一个多维数组,最好用[[0] for i in range(n)]这种。

优化

由dp[i][j] = dp[i-1][j] + dp[i][j-1]可知,当我们计算第i行的值的时候是不需要1~i-2行的值,那么只需要一个一维数组保存上一行的信息即可。

dp[i] = dp[i] + dp[i-1],每次从左到右更新dp,这里的dp[i-1]就是i左边那一格,等号后面的dp[i]还没更新,是上一行第i列的值。

  1. class Solution:
  2. def minPathSum(self, grid: List[List[int]]) -> int:
  3. m = len(grid)
  4. n = len(grid[0])
  5. dp = [0 for i in range(n)]
  6. dp[0] = grid[0][0]
  7. #初始化第0行的值
  8. for i in range(1,n):
  9. dp[i] = dp[i-1] + grid[0][i]
  10. for i in range(1,m):
  11. dp[0] = dp[0] + grid[i][0]
  12. for j in range(1,n):
  13. dp[j] = min(dp[j], dp[j-1]) + grid[i][j]
  14. return dp[n-1]

72. 编辑距离(hard)

题目描述

72

给定两个单词 word1 和 word2,计算出将 word1 转换成 word2 所使用的最少操作数 。

你可以对一个单词进行如下三种操作:

  1. 插入一个字符
  2. 删除一个字符
  3. 替换一个字符

示例 1:

  1. 输入: word1 = "horse", word2 = "ros"
  2. 输出: 3
  3. 解释:
  4. horse -> rorse (将 'h' 替换为 'r')
  5. rorse -> rose (删除 'r')
  6. rose -> ros (删除 'e')

示例 2:

  1. 输入: word1 = "intention", word2 = "execution"
  2. 输出: 5
  3. 解释:
  4. intention -> inention (删除 't')
  5. inention -> enention (将 'i' 替换为 'e')
  6. enention -> exention (将 'n' 替换为 'x')
  7. exention -> exection (将 'n' 替换为 'c')
  8. exection -> execution (插入 'u')

题目思路

状态定义

每个阶段状态pd[i][j],定义为word1长度为i,word2长度为j,将word1变成word2需要的最小操作数。

注意,这里我们只专注于操作数, pd[i][j]可以理解成word1[:i]变成word2[:j]需要的操作数。

选择

我们遍历两个单词每个字符,如果word1[i]==wordr2[j],那么什么都不需要做。pd[i][j] = pd[i-1][j-1],i,j两个字符就被排除了,只需要算剩下的字符。

如果不相等,有三种选择:

  1. 插入,在word1 i处插入word2[j]。即 dp[i][j] = dp[i][j-1] + 1
  2. 删除,删除word1[i],即 dp[i][j] = 1 + dp[i-1][j]
  3. 替换, dp[i][j] = dp[i-1][j-1] + 1

综上,只需要取dp[i][j] = min(dp[i][j-1], dp[i-1][j], dp[i-1][j-1]) + 1

Base case

当i或j为0时,有一个单词长度为0,自然只能不断删除或者插入。需要两个for循环来初始化pd[i][0]和pd[0][j]的值。

题解

  1. class Solution:
  2. def minDistance(self, word1: str, word2: str) -> int:
  3. n, m = len(word1), len(word2)
  4. dp = [[0 for i in range(m+1)] for j in range(n+1)] #注意单词长度从0~len(word1)所以要+1
  5. for i in range(1, n+1):
  6. dp[i][0] = dp[i-1][0] + 1
  7. for i in range(1, m+1):
  8. dp[0][i] = dp[0][i-1] + 1
  9. for i in range(1,n+1):
  10. for j in range(1,m+1):
  11. if word1[i-1] == word2[j-1]: # 这里也要注意下标要-1
  12. dp[i][j] = dp[i-1][j-1]
  13. else:
  14. dp[i][j] = min(dp[i][j-1], dp[i-1][j], dp[i-1][j-1]) + 1
  15. return dp[n][m]

优化

同上题一样,可以画图观察dp[i][j]需要那些量,发现dp[i][j]只与dp[i-1][j] , dp[i-1][j-1] , dp[i][j-1]相关。与之前不同的是,这里多了个dp[i-1][j-1]需要额外的变量保存,不然我们更新了dp[i-1]再来计算dp[i]就得不到上一行的i-1处的值,然而这又是我们需要的,所以额外用一个变量保存即可。

  1. class Solution:
  2. def minDistance(self, word1: str, word2: str) -> int:
  3. n, m = len(word1), len(word2)
  4. dp = [j for j in range(m+1)] #注意单词长度从0~len(word1)所以要+1
  5. for i in range(1,n+1):
  6. temp = dp[0]
  7. dp[0] = i
  8. for j in range(1,m+1):
  9. pre = temp
  10. temp = dp[j]
  11. if word1[i-1] == word2[j-1]: # 这里也要注意下标要-1
  12. dp[j] = pre
  13. else:
  14. dp[j] = min(dp[j-1], dp[j], pre) + 1
  15. return dp[m]

64. 最小路径和

64

给定一个包含非负整数的 m x n 网格,请找出一条从左上角到右下角的路径,使得路径上的数字总和为最小。

说明:每次只能向下或者向右移动一步。

  1. 示例:
  2. 输入:
  3. [
  4.   [1,3,1],
  5. [1,5,1],
  6. [4,2,1]
  7. ]
  8. 输出: 7
  9. 解释: 因为路径 13111 的总和最小。

dp[i][j]:表示到(i,j)的最小路径和

那么怎么才能到达(i,j)处呢,有两种要么从(i-1,j)要么从(i,j-1)走来。所以:dp[i][j] = min(dp[i-1][j],dp[i][j-1]) + grid[i][j]

优化

我们发现这个二维dp数组的值取决于,左边的值和上面的值。dp[1][j]第一行的值也就取决于dp[0][j]dp[1][j-1],我们只需要维护一个一维数组即可。

从第0行开始,初始化一个dp[j],那么dp[j] = dp[j-1] + grid[j],因为第0行只能往右边走。

第1行:dp[j] = min(dp[j], dp[j-1]) + grid[j],因为一开始dp[j]还没有更新所以他保留的是上一行的值,相当于dp[i-1][j]。这里的dp[j-1]相当于dp[i][j-1]。因此,状态转移方程为:dp[j] = min(dp[j], dp[j-1]) + grid[j]

BaseCase: 我们需要初始化第一行。

题解

  1. class Solution:
  2. def minPathSum(self, grid: List[List[int]]) -> int:
  3. m = len(grid)
  4. n = len(grid[0])
  5. dp = [0 for i in range(n)]
  6. dp[0] = grid[0][0]
  7. #初始化第0行的值
  8. for i in range(1,n):
  9. dp[i] = dp[i-1] + grid[0][i]
  10. for i in range(1,m):
  11. dp[0] = dp[0] + grid[i][0]
  12. for j in range(1,n):
  13. dp[j] = min(dp[j], dp[j-1]) + grid[i][j]
  14. return dp[n-1]

62. 不同路径

一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为“Start” )。

机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为“Finish”)。

问总共有多少条不同的路径?

  1. 示例 1:
  2. 输入: m = 3, n = 2
  3. 输出: 3
  4. 解释:
  5. 从左上角开始,总共有 3 条路径可以到达右下角。
  6. 1. 向右 -> 向右 -> 向下
  7. 2. 向右 -> 向下 -> 向右
  8. 3. 向下 -> 向右 -> 向右
  9. 示例 2:
  10. 输入: m = 7, n = 3
  11. 输出: 28

思路同上题

题解

  1. class Solution:
  2. def uniquePaths(self, m: int, n: int) -> int:
  3. dp = [[0] for i in range(n)]
  4. for i in range(n):
  5. dp[i] = 1
  6. for i in range(1,m):
  7. for j in range(1,n):
  8. dp[j] = dp[j-1] + dp[j]
  9. return dp[n-1]

343. 整数拆分

343

给定一个正整数 n,将其拆分为至少两个正整数的和,并使这些整数的乘积最大化。 返回你可以获得的最大乘积。

  1. 示例 1:
  2. 输入: 2
  3. 输出: 1
  4. 解释: 2 = 1 + 1, 1 × 1 = 1
  5. 示例 2:
  6. 输入: 10
  7. 输出: 36
  8. 解释: 10 = 3 + 3 + 4, 3 × 3 × 4 = 36

因为题目要求是,至少拆为2个,并使他们乘积最大。

状态: 乘积。我们用dp[i]表示整数i拆分后的最大乘积。

选择:怎么得到dp[i]的?假设i拆成,j和i-j两个数。那么直观上dp[i] = dp[j] * dp[i-j]。这里有一个错误,dp[j]不一定比j大,因为题目必须让我们拆成至少两个数再乘,如果dp[j]比j小,那还不如j就不拆了,dp[i] = j * dp[i-j]。例如 2拆成 1 * 1 = 1 < 2。所以dp[i]改进后:

状态转移方程dp[i] = max(dp[j], j) * max(dp[i-j], i-j)

  1. class Solution:
  2. def integerBreak(self, n: int) -> int:
  3. num = n+1
  4. dp = [0 for i in range(num)]
  5. for i in range(2, num):
  6. temp = 1
  7. for j in range(1, i):
  8. temp = max(temp,max(dp[j], j) * max(dp[i-j],i-j))
  9. dp[i] = temp
  10. return dp[n]

这里我犯了一个错误,没有temp,直接dp[i] = max(temp,max(dp[j], j) * max(dp[i-j],i-j)),所以没有保存下最大值。

第 k 个数

leetcode

有些数的素因子只有 3,5,7,请设计一个算法找出第 k 个数。注意,不是必须有这些素因子,而是必须不包含其他的素因子。例如,前几个数按顺序应该是 1,3,5,7,9,15,21。

  1. 示例 1:
  2. 输入: k = 5
  3. 输出: 9

这里的数的因子只能是3,5,7的组合。

我们发现,从1开始下一个数就是min(1*3, 1*5, 1*7),在下一个就是min(3*3, 1*5, 1*7),为什么只考虑min(3*3, 1*5, 1*7),不考虑3*5, 3*7呢?

因为我们的数列是从小到大的,很明显后面的数3乘以5和7肯定大于前面的数1乘以5和7。所以不用考虑3*5, 3*7

因此发现,用三个指针分别从左往右扫,三个指针分别代表要将指向的数乘以3或5或7,每次我们选择当前最小值即可。

状态转移方程

pd[i] = min(dp[p1]3, dp[p2]5, dp[p3]*7),这里p1只负责将它指向的数乘以3,同理p2,p3分别代表乘以5和7。这三个指针都从左往右扫描数组。

题解

  1. class Solution:
  2. def getKthMagicNumber(self, k: int) -> int:
  3. dp = [1]
  4. p1,p2,p3 = 0,0,0
  5. for i in range(k-1):
  6. Min = min(dp[p1]*3, dp[p2]*5, dp[p3]*7)
  7. dp.append(Min)
  8. if dp[p1]*3==Min: p1+=1
  9. if dp[p2]*5==Min: p2+=1
  10. if dp[p3]*7==Min: p3+=1
  11. return dp[k-1]

32. 最长有效括号

32

题目描述

给定一个只包含 '(' 和 ')' 的字符串,找出最长的包含有效括号的子串的长度。

  1. 示例 1:
  2. 输入: "(()"
  3. 输出: 2
  4. 解释: 最长有效括号子串为 "()"
  5. 示例 2:
  6. 输入: ")()())"
  7. 输出: 4
  8. 解释: 最长有效括号子串为 "()()"

解题思路

状态,好定义。dp[i]表示以第i个字符结尾的最长有效括号。结尾一般是')'结尾。

选择,即怎么得到dp[i]。因为我们只考虑s[i]==')'的情况,所以:

  1. s[i]=')'时,若s[i-1]='(',则dp[i] = dp[i-2]+2
  2. s[i-1]=')',若s[i-1-dp[i-1]]='(',则dp[i] = d[i-1] + 2 + dp[i-2-dp[i-1]] #将s[i-1-dp[i-1]]之前的字符也考虑在内,所以加上dp[i-2-dp[i-1]],稍微想想就明白

Base Case,都为0。这道题要注意判断条件。

题解

  1. class Solution:
  2. def longestValidParentheses(self, s: str) -> int:
  3. # dp初始化为0
  4. # 当s[i]=')'时,若s[i-1]='(',则dp[i] = dp[i-2]+2
  5. # 若s[i-1]=')',若s[i-1-dp[i-1]]='(',则dp[i] = d[i-1] + 2 + dp[i-2-dp[i-1]]
  6. # 边界条件=号判断再想想
  7. dp = [0 for i in range(len(s))]
  8. for i in range(1,len(s)):
  9. if s[i]==')':
  10. if s[i-1]=='(':
  11. # 这里不用判断i-2>=0的原因是,因为只有i=1时,i-2才会小于0也就是-1,
  12. # 然而dp[-1]=0的,所以不用管。之后i-2都大于或等于0
  13. dp[i] = dp[i-2] + 2
  14. # i-1-dp[i-1]就是指向了与 s[i]相对应的那个有效顺括号当然要判断它是否大于等于0以及他是否等于'(',
  15. # 如果不能同时满足这两个条件,那么dp[i]=0,也就值不变
  16. elif i-1-dp[i-1]>=0 and s[i-1-dp[i-1]]=='(':
  17. # 这里dp[i-2-dp[i-1]]也就是之前的值了,也要判断下是否大于或等于0,否则不加上他
  18. dp[i] = dp[i-1] + 2 + dp[i-2-dp[i-1]] if i-2-dp[i-1]>=0 else dp[i-1] + 2
  19. if dp:
  20. return max(dp)
  21. else:
  22. return 0

1143. 最长公共子序列

1143

题目

给定两个字符串 text1 和 text2,返回这两个字符串的最长公共子序列。

一个字符串的 子序列 是指这样一个新的字符串:它是由原字符串在不改变字符的相对顺序的情况下删除某些字符(也可以不删除任何字符)后组成的新字符串。

例如,"ace" 是 "abcde" 的子序列,但 "aec" 不是 "abcde" 的子序列。两个字符串的「公共子序列」是这两个字符串所共同拥有的子序列。

若这两个字符串没有公共子序列,则返回 0。

  1. 示例 1:
  2. 输入:text1 = "abcde", text2 = "ace"
  3. 输出:3
  4. 解释:最长公共子序列是 "ace",它的长度为 3

状态:dp[i][j],text1[:i]与text2[:j]最长公共子序列

选择:text1[i] == text2[j]或者不等

转移方程: 相等时dp[i][j] = dp[i-1][j-1]+1,不等时dp[i][j] = max(dp[i-1][j], dp[i][j-1])

同样可以优化成一个以维dp数组解决,同上面的编辑距离优化问题:

  1. class Solution:
  2. def longestCommonSubsequence(self, text1: str, text2: str) -> int:
  3. # dp[i][j] :text1[:i] 与 text2[:j]最长公共子序列
  4. # 如果text1[i] == text2[j] , dp[i][j] = dp[i-1]dp[j-1] + 1
  5. # 其他 dp[i][j] = max(dp[i-1][j], dp[i][j-1])
  6. dp = [0 for i in range(len(text2)+1)]
  7. for i in range(1,len(text1)+1):
  8. temp = dp[0]
  9. for j in range(1,len(dp)):
  10. pre = temp
  11. temp = dp[j]
  12. if text1[i-1]==text2[j-1]:
  13. dp[j] = pre + 1
  14. else:
  15. dp[j] = max(dp[j], dp[j-1])
  16. return dp[len(text2)]

注意这里保存dp[i-1][j-1]的操作,再第一层循环初始化temp = dp[0], 第二层pre = temp; temp = dp[j]这样就可以下次循环仍能取到上次的dp[j-1]的值。

leetcode刷题-- 5. 动态规划的更多相关文章

  1. LeetCode刷题总结-动态规划篇

    本文总结LeetCode上有动态规划的算法题,推荐刷题总数为54道.具体考点分析如下图: 1.中心扩展法 题号:132. 分割回文串 II,难度困难 2.背包问题 题号:140. 单词拆分 II,难度 ...

  2. C#LeetCode刷题-动态规划

    动态规划篇 # 题名 刷题 通过率 难度 5 最长回文子串   22.4% 中等 10 正则表达式匹配   18.8% 困难 32 最长有效括号   23.3% 困难 44 通配符匹配   17.7% ...

  3. LeetCode刷题专栏第一篇--思维导图&时间安排

    昨天是元宵节,过完元宵节相当于这个年正式过完了.不知道大家有没有投入继续投入紧张的学习工作中.年前我想开一个Leetcode刷题专栏,于是发了一个投票想了解大家的需求征集意见.投票于2019年2月1日 ...

  4. LeetCode刷题总结-数组篇(上)

    数组是算法中最常用的一种数据结构,也是面试中最常考的考点.在LeetCode题库中,标记为数组类型的习题到目前为止,已累计到了202题.然而,这202道习题并不是每道题只标记为数组一个考点,大部分习题 ...

  5. LeetCode刷题总结-数组篇(中)

    本文接着上一篇文章<LeetCode刷题总结-数组篇(上)>,继续讲第二个常考问题:矩阵问题. 矩阵也可以称为二维数组.在LeetCode相关习题中,作者总结发现主要考点有:矩阵元素的遍历 ...

  6. LeetCode刷题总结-数组篇(下)

    本期讲O(n)类型问题,共14题.3道简单题,9道中等题,2道困难题.数组篇共归纳总结了50题,本篇是数组篇的最后一篇.其他三个篇章可参考: LeetCode刷题总结-数组篇(上),子数组问题(共17 ...

  7. LeetCode刷题总结-树篇(上)

          引子:刷题的过程可能是枯燥的,但程序员们的日常确不乏趣味.分享一则LeetCode上名为<打家劫舍 |||>题目的评论: 如有兴趣可以从此题为起点,去LeetCode开启刷题之 ...

  8. LeetCode刷题笔记和想法(C++)

    主要用于记录在LeetCode刷题的过程中学习到的一些思想和自己的想法,希望通过leetcode提升自己的编程素养 :p 高效leetcode刷题小诀窍(这只是目前对我自己而言的小方法,之后会根据自己 ...

  9. LeetCode刷题的一点个人建议和心得

    目录 1.    为什么我们要刷LeetCode? 2.    LeetCode的现状和问题 3.    本文的初衷 4.    LeetCode刷题建议 4.1入门数据结构,打基础阶段 4.2 建立 ...

随机推荐

  1. go之二进制协议gob和msgpack

    文章引用自 二进制协议gob和msgpack介绍 本文主要介绍二进制协议gob及msgpack的基本使用. 最近在写一个gin框架的session服务时遇到了一个问题,Go语言中的json包在序列化空 ...

  2. Android App测试计划和设计测试矩阵

    Android APP :日程管理APP 测试计划(Test Plan): 编号 测试时间 测试类型 测试计划 1. 5.1~5.5 单元测试 单元测试是由程序员自己来完成,程序员有责任编写功能代码, ...

  3. 动手实现CapsNet系列——1 概述

    Geoffrey Hinton是深度学习的开创者之一,反向传播等神经网络经典算法发明人,他在17年年底和他的团队发表了两篇论文,介绍了一种全新的神经网络,这种网络基于一种称为胶囊(Capsule)的结 ...

  4. Git - 01. git config

    1. 概述 管理 git 配置文件命令 配置算是 git 的 meta 大概了解下就行 写这个的原因, 是因为 安装 的时候需要配置 用户名 和 密码 这个操作本质上, 是对属性的配置 先简单知道下操 ...

  5. Java switch的用法

    控制流程语句之→switch选择判断语句  注意事项: 1.多个case后面的值不能重复: 2.switch后面小括号当中只能是下列数据类型: 基本数据类型:byte.short.char.int 引 ...

  6. 公告 & 留言板 & 随想录

    欢迎dalao在评论区留言 \(Q \omega Q\) 公告部分: 博客文章的更新一般被放在周末 当然还是可能会咕 自从改了博客的主题之后,文章中的引用好像都会显示出一堆乱码. 由于之前写过的博文不 ...

  7. 【PAT甲级】1095 Cars on Campus (30 分)

    题意:输入两个正整数N和K(N<=1e4,K<=8e4),接着输入N行数据每行包括三个字符串表示车牌号,当前时间,进入或离开的状态.接着输入K次询问,输出当下停留在学校里的车辆数量.最后一 ...

  8. 广度优先搜索(BFS)与深度优先搜索(DFS)的对比及优缺点

    深搜,顾名思义,是深入其中.直取结果的一种搜索方法. 如果深搜是一个人,那么他的性格一定倔得像头牛!他从一点出发去旅游,只朝着一个方向走,除非路断了,他绝不改变方向!除非四个方向全都不通或遇到终点,他 ...

  9. PHP将json或对象转成数组

    今天老大突然给了我一个小任务,给我一个txt文件,里边是很多的json字串,要求将这些字串转换成php中的数组: 于是开足火力,用了将进5分钟的时间完成了任务,代码如下: $jsonStr = fil ...

  10. Python NumPy中数组array.min(0)返回数组

    如果没有参数min()返回一个标量,如果有参数0表示沿着列,1表示沿着行.