目录
1-Split a String in Balanced Strings-easy。字符串
2-Queens That Can Attack the King-medium。数组、网格
3-Dice Roll Simulation-medium。
4-Maximum Equal Frequency-hard。
1-Split a String in Balanced Strings-easy。字符串
Balanced strings are those who have equal quantity of 'L' and 'R' characters.
Given a balanced string
s
split it in the maximum amount of balanced strings.
Return the maximum amount of splitted balanced strings.
Example 1:
Input: s = "RLRRLLRLRL"
Output: 4
Explanation: s can be split into "RL", "RRLL", "RL", "RL", each substring contains same number of 'L' and 'R'.
Example 2:
Input: s = "RLLLLRRRLR"
Output: 3
Explanation: s can be split into "RL", "LLLRRR", "LR", each substring contains same number of 'L' and 'R'.
Example 3:
Input: s = "LLLLRRRR"
Output: 1
Explanation: s can be split into "LLLLRRRR".
Constraints:
-
1 <= s.length <= 1000
-
s[i] = 'L' or 'R'
因为是求最大个数,所以要把子段切分得尽量小才行,贪心法则在这里奏效,一旦找到平衡的res就加一,然后LR的计数清0
class Solution(object):
def balancedStringSplit(self, s):
"""
:type s: str
:rtype: int
"""
if not s:
return 0
balance = 0
res = 0
for c in s:
if c == 'L':
balance += 1
else:
balance -= 1
if balance == 0:
res += 1
balance = 0
return res
2-Queens That Can Attack the King-medium。数组、网格
On an 8x8 chessboard, there can be multiple Black Queens and one White King.
Given an array of integer coordinates
queens
that represents the positions of the Black Queens, and a pair of coordinates
king
that represent the position of the White King, return the coordinates of all the queens (in any order) that can attack the King.
Example 1:
Input: queens = [[0,1],[1,0],[4,0],[0,4],[3,3],[2,4]], king = [0,0]
Output: [[0,1],[1,0],[3,3]]
Explanation:
The queen at [0,1] can attack the king cause they're in the same row.
The queen at [1,0] can attack the king cause they're in the same column.
The queen at [3,3] can attack the king cause they're in the same diagnal.
The queen at [0,4] can't attack the king cause it's blocked by the queen at [0,1].
The queen at [4,0] can't attack the king cause it's blocked by the queen at [1,0].
The queen at [2,4] can't attack the king cause it's not in the same row/column/diagnal as the king.
Example 2:
Input: queens = [[0,0],[1,1],[2,2],[3,4],[3,5],[4,4],[4,5]], king = [3,3]
Output: [[2,2],[3,4],[4,4]]
Example 3:
Input: queens = [[5,6],[7,7],[2,1],[0,7],[1,6],[5,1],[3,7],[0,3],[4,0],[1,2],[6,3],[5,0],[0,4],[2,2],[1,1],[6,4],[5,4],[0,0],[2,6],[4,5],[5,2],[1,4],[7,5],[2,3],[0,5],[4,2],[1,0],[2,7],[0,1],[4,6],[6,1],[0,6],[4,3],[1,7]], king = [3,4]
Output: [[2,3],[1,4],[1,6],[3,7],[4,3],[5,4],[4,5]]
Constraints:
-
1 <= queens.length <= 63
-
queens[0].length == 2
-
0 <= queens[i][j] < 8
-
king.length == 2
-
0 <= king[0], king[1] < 8
- At most one piece is allowed in a cell.
比较虚张声势的一题,其实就是求距离King坐标最近的一圈Q的8个坐标,如果存在的话。考点是如何把代码写得更简洁和判断第一第二对称轴的公式
- 遍历所有坐标判断是否是距离King最近的一周,是的话就更新
- 注意输入的数据范围,最多不超过8*8的网格,所以转换思路,从King出发,一圈一圈往外找找到了该个方向的就继续找下一个方向。
# DIY
class Solution(object):
def queensAttacktheKing(self, queens, king):
"""
:type queens: List[List[int]]
:type king: List[int]
:rtype: List[List[int]]
"""
if not queens or not king:
return 0
res = []
up = [None, king[1]]
down = [None, king[1]]
left = [king[0], None]
right = [king[0], None]
left_up_dia = [None, None]
left_down_dia = [None, None]
right_up_dia = [None, None]
right_down_dia = [None, None]
for q in queens:
if q[0] == king[0]:
if q[1] < king[1]:
if left[1] == None:
left[1] = q[1]
else:
left[1] = max(left[1], q[1])
else:
if right[1] == None:
right[1] = q[1]
else:
right[1] = min(right[1], q[1])
elif q[1] == king[1]:
if q[0] < king[0]:
if up[0] == None:
up[0] = q[0]
else:
up[0] = max(up[0], q[0])
else:
if down[0] == None:
down[0] = q[0]
else:
down[0] = min(down[0], q[0])
elif q[1] - q[0] == king[1] - king[0]:
if q[0] < king[0]:
if left_up_dia[0] == None:
left_up_dia[0] = q[0]
left_up_dia[1] = q[1]
else:
if q[0] > left_up_dia[0]:
left_up_dia[0] = q[0]
left_up_dia[1] = q[1]
else:
if right_down_dia[0] == None:
right_down_dia[0] = q[0]
right_down_dia[1] = q[1]
else:
if q[0] < right_down_dia[0]:
right_down_dia[0] = q[0]
right_down_dia[1] = q[1]
elif q[1] + q[0] == king[1] + king[0]:
if q[0] < king[0]:
if left_down_dia[0] == None:
left_down_dia[0] = q[0]
left_down_dia[1] = q[1]
else:
if q[0] > left_down_dia[0]:
left_down_dia[0] = q[0]
left_down_dia[1] = q[1]
else:
if right_up_dia[0] == None:
right_up_dia[0] = q[0]
right_up_dia[1] = q[1]
else:
if q[0] < right_up_dia[0]:
right_up_dia[0] = q[0]
right_up_dia[1] = q[1]
if up[0] != None:
res.append(up)
if down[0] != None:
res.append(down)
if left[1] != None:
res.append(left)
if right[1] != None:
res.append(right)
if left_up_dia[0] != None:
res.append(left_up_dia)
if left_down_dia[0] != None:
res.append(left_down_dia)
if right_up_dia[0] != None:
res.append(right_up_dia)
if right_down_dia[0] != None:
res.append(right_down_dia)
return res
# 简洁的写法
class Solution(object):
def queensAttacktheKing(self, queens, king):
"""
:type queens: List[List[int]]
:type king: List[int]
:rtype: List[List[int]]
"""
# 注意这里不能有[0, 0]
around = [[-1, -1], [-1, 0], [-1, 1], [0, -1], [0, 1], [1, -1], [1, 0], [1, 1]]
board = [[0 for _ in range(8)] for _ in range(8)]
res = []
for q in queens:
board[q[0]][q[1]] = 1
for i in range(8):
k = 1
while True:
x = around[i][0] * k + king[0]
y = around[i][1] * k + king[1]
if x >= 0 and x < 8 and y >= 0 and y < 8:
if board[x][y]:
res.append([x, y])
break
else:
break
k += 1
return res
3-Dice Roll Simulation-medium。DP
A die simulator generates a random number from 1 to 6 for each roll. You introduced a constraint to the generator such that it cannot roll the number
i
more than
rollMax[i]
(1-indexed) consecutive times.
Given an array of integers
rollMax
and an integer
n
, return the number of distinct sequences that can be obtained with exact
n
rolls.
Two sequences are considered different if at least one element differs from each other. Since the answer may be too large, return it modulo
10^9 + 7
.
Example 1:
Input: n = 2, rollMax = [1,1,2,2,2,3]
Output: 34
Explanation: There will be 2 rolls of die, if there are no constraints on the die, there are 6 * 6 = 36 possible combinations. In this case, looking at rollMax array, the numbers 1 and 2 appear at most once consecutively, therefore sequences (1,1) and (2,2) cannot occur, so the final answer is 36-2 = 34.
Example 2:
Input: n = 2, rollMax = [1,1,1,1,1,1]
Output: 30
Example 3:
Input: n = 3, rollMax = [1,1,1,2,2,3]
Output: 181
Constraints:
-
1 <= n <= 5000
-
rollMax.length == 6
-
1 <= rollMax[i] <= 15
初始思路是按照Catalan递推公式那样,重复数字为1、2、3、…n次这样累积出所有可能性,因为给定rollMax也可以知道1-6每个数最多出现多少次,根据最多出现多少次分组。这种想法在设计子问题的时候卡住了,因为并不能分解成T(k)*T(n-k)这种可能性相乘
- 用3维数组,dp[i][j][k]表示摇色子i次,数字j连续出现k次(不确定),所以还没搞懂为什么这些可能性是直接相加而非乘性的关系。
class Solution(object):
def dieSimulator(self, n, rollMax):
"""
:type n: int
:type rollMax: List[int]
:rtype: int
"""
if n < 0 or len(rollMax) != 6:
return 0
dp = [[[0 for _ in range(16)] for _ in range(6)] for _ in range(n+1)]
MOD = 10**9 + 7
dp[0][0][0] = 1
for i in range(1, n+1):
for k in range(6):
for j in range(2, rollMax[k]+1):
dp[i][k][j] = dp[i-1][k][j-1]
sums = 0
for j in range(6):
if j == k and i != 1:
continue
for l in range(16):
sums += dp[i-1][j][l]
sums %= MOD
dp[i][k][1] = sums
res = 0
for i in range(6):
for j in range(16):
res += dp[n][i][j]
res %= MOD
return res
4-Maximum Equal Frequency-hard。
Given an array
nums
of positive integers, return the longest possible length of an array prefix of
nums
, such that it is possible to remove exactly one element from this prefix so that every number that has appeared in it will have the same number of occurrences.
If after removing one element there are no remaining elements, it's still considered that every appeared number has the same number of ocurrences (0).
Example 1:
Input: nums = [2,2,1,1,5,3,3,5]
Output: 7
Explanation: For the subarray [2,2,1,1,5,3,3] of length 7, if we remove nums[4]=5, we will get [2,2,1,1,3,3], so that each number will appear exactly twice.
Example 2:
Input: nums = [1,1,1,2,2,2,3,3,3,4,4,4,5]
Output: 13
Example 3:
Input: nums = [1,1,1,2,2,2]
Output: 5
Example 4:
Input: nums = [10,2,8,9,3,8,1,5,2,3,7,6]
Output: 8
Constraints:
-
2 <= nums.length <= 10^5
-
1 <= nums[i] <= 10^5
初始想法就是前向后向遍历,但不能确定相通的频数是多少,不适用。
class Solution(object):
def maxEqualFreq(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
if not nums:
return 0
n = len(nums)
ca = [0]*(10**5+5)
cb = [0]*(10**5+5)
res = 1
hv = mx = 0
for i in range(n):
tmp = nums[i]
ca[tmp] += 1
cb[ca[tmp]] += 1
mx = max(mx, ca[tmp])
if ca[tmp] == 1:
hv += 1
else:
cb[ca[tmp]-1] -= 1
if mx == 1 or (cb[1] == 1 and cb[mx] == hv-1) or (cb[mx] == 1 and cb[mx-1] == hv-1):
res = i+1
return res