JZX轻语:简
LeetCode 1053 - 交换一次的先前排列
发表于2024年06月11日
为了保证交换后的数字在小于原数字的要求下尽可能大,交换的位置应尽可能靠右。因此,我们从右往左扫描,找到第一个不满足升序的位置(即对于位置i
有arr[i] > arr[i - 1]
),然后在其右边找到最大的比它小的数(如果有重复值, 则交换最靠左的)arr[j]
,交换这两个数即可。
贪心可行性的证明:
证明上述的待交换左侧位置
i
是最优的:如果存在一个更优的位置k
,那么arr[k]
必然在arr[i]
右边,由于位置i
右侧(不包括i
)的数都是递增的,如果k
作为交换的左侧位置,则交换后的数必然比原数更大,与要求矛盾。证明上述的待交换右侧位置
j
是最优的:如果位于i
右侧存在一个更优的位置l
,那么arr[l]
必然大于arr[j]
,而arr[j]
是arr[i]
右侧最大的比arr[i]
小的数,因此交换arr[l]
和arr[i]
后,交换后的数必然比原数更大,与要求矛盾。
class Solution:
def countBattleships(self, board: List[List[str]]) -> int:
ans = 0
for i in range(len(board)):
for j in range(len(board[i])):
if board[i][j] == 'X' and (i == 0 or board[i - 1][j] == '.') and (j == 0 or board[i][j - 1] == '.'):
ans += 1
return ans