474. 1和0
解法:动态规划
(官方解答可参考:官方解答)
背景:背包问题
背包问题(Knapsack problem)是一种组合优化的NP完全问题。 问题可以描述为:给定一组物品,每种物品都有自己的重量和价格,在限定的总重量内,我们如何选择,才能使得物品的总价格最高。
通过对题意进行理解,发现该问题能够被归类为背包问题。
这道题和经典的背包问题非常相似,但是和经典的背包问题只有一种容量不同,这道题有两种容量,即选取的字符串子集中的 0 和 1 的数量上限。
经典的背包问题可以使用二维动态规划求解,两个维度分别是物品和容量。这道题有两种容量,因此需要使用三维动态规划求解,三个维度分别是字符串、0 的容量和 1 的容量。
定义数组dp[length][m][n],其中length为字符串数组的长度,对于dp数组中元素dp[i][j][k]表示对于字符串数组中前i个字符串,0数量不超过j且1数量不超过k条件下,最大子集的长度。对于第i字符串,我们统计得到其0和1的个数分别为zeros和ones,其状态判断过程为:
class Solution:
def findMaxForm(self, strs: List[str], m: int, n: int) -> int:
length = len(strs)
# length*m*n
dp = [[[0]*(n+1) for i in range(m+1)] for _ in range(length+1)]
for i in range(length):
_index = i + 1
zeros = 0
ones = 0
for char in strs[i]:
if char == "0":
zeros += 1
else:
ones += 1
# print(zeros, ones)
for j in range(m+1):
for k in range(n+1):
# print(_index, j, k)
if j < zeros or k < ones:
dp[_index][j][k] = dp[_index-1][j][k]
else:
dp[_index][j][k] = max(dp[_index-1][j][k], dp[_index-1][j-zeros][k-ones] + 1)
return dp[-1][-1][-1]
961. 在长度为2N的数组中找出重复N次的元素
解法:排序+遍历
根据题意可知,2N数组中N+1中元素,其中有某个元素出现N次,对此我们可以判断只有出现N次的元素有重复,其余元素均出现一次。因此我们可以通过排序,再进行遍历判断当前值和前一位置值是否相等来找到重复元素。
class Solution:
def repeatedNTimes(self, nums: List[int]) -> int:
nums.sort()
for i in range(1, len(nums)):
if nums[i] == nums[i-1]:
return nums[i]