目录
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。
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
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
比较虚张声势的一题,其实就是求距离King坐标最近的一圈Q的8个坐标,如果存在的话。考点是如何把代码写得更简洁和判断第一第二对称轴的公式
# 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
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)这种可能性相乘
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
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