第一天开始用python刷题, 生疏太多了.
好题总结如下:
80 在一个排好序的数组中, 去除出现了超过k次的元素
就两个叠加的分类:
分类条件1: 如果元素已经出现了k次怎么办
分类条件2: nums[head]和nums[i]相等吗
1,2同时满足 => 不用管, 直接看下一个i
1满足, 2不满足 => 新元素出现了, 快加上
1不满足, 2管你满足不 => 都得把i指向的元素加上
class Solution:
def removeDuplicates(self, nums: List[int], k:int) -> int:
if len(nums) <= k:
return len(nums)
head = k
for i in range(k, len(nums)):
# 我们能关注的东西:nums[head],nums[head - k + 1]和nums[i]
# 已经出现了k次
if nums[head - 1] == nums[head - k]:
if nums[i] != nums[head - 1]:
nums[head] = nums[i]
head+=1
else:
continue
#出现的次数小于k次,还能加
else:
nums[head] = nums[i]
head+=1
大佬们当然有更简单的写法:
def solve(k):
u = 0
for x in nums:
if u < k or nums[u - k] != x:
nums[u] = x
u += 1
return u
169 找众数的投票算法
“同归于尽消杀法” :
由于多数超过50%, 比如100个数,那么多数至少51个,剩下少数是49个。
第一个到来的士兵,直接插上自己阵营的旗帜占领这块高地,此时领主 winner 就是这个阵营的人,现存兵力 count = 1。
如果新来的士兵和前一个士兵是同一阵营,则集合起来占领高地,领主不变,winner 依然是当前这个士兵所属阵营,现存兵力 count++;
如果新来到的士兵不是同一阵营,则前方阵营派一个士兵和它同归于尽。 此时前方阵营兵力count --。(即使双方都死光,这块高地的旗帜 winner 依然不变,因为已经没有活着的士兵可以去换上自己的新旗帜)
当下一个士兵到来,发现前方阵营已经没有兵力,新士兵就成了领主,winner 变成这个士兵所属阵营的旗帜,现存兵力 count ++。
public int majorityElement(int[] nums) {
int winner = nums[0];
int count = 1;
for (int i = 1; i < nums.length; i++) {
if (winner == nums[i]) {
count++;
} else if (count == 0) {
winner = nums[i];
count++;
} else {
count--;
}
}
return winner;
}
就这样各路军阀一直以这种以一敌一同归于尽的方式厮杀下去,直到少数阵营都死光,那么最后剩下的几个必然属于多数阵营,winner 就是多数阵营。(多数阵营 51个,少数阵营只有49个,死剩下的2个就是多数阵营的人)
88 merge sort的merge步骤
真的是手很生啊, 太久没写了, 这道简单都做了很久, 我的方法是从nums1的后部分开始往前推, 这样能避免覆写的问题, 和官方题解的思路和代码也基本相似:
class Solution(object):
def merge(self, nums1, m, nums2, n):
a = m-1
b = n -1
for i in range(m+n-1, -1, -1):
if a == -1:
nums1[i] = nums2[b]
b-=1
continue
if b == -1:
nums1[i] = nums1[a]
a-=1
continue
if nums1[a] > nums2[b]:
nums1[i] = nums1[a]
a-=1
else:
nums1[i] = nums2[b]
b-=1
官方题解给的太暴力了:
class Solution:
def merge(self, nums1: List[int], m: int, nums2: List[int], n: int) -> None:
"""
Do not return anything, modify nums1 in-place instead.
"""
nums1[m:] = nums2
nums1.sort()
27 [3,2,2,3]去除2
很傻的一道题, 直接双指针就可以了, 但自己却还是想了挺久lol
class Solution:
def removeElement(self, nums: List[int], val: int) -> int:
head = 0
for i in range(len(nums)):
if nums[i] != val:
nums[head] = nums[i]
head+=1
return head
26 删除有序数组的重复项
同样双指针:
class Solution:
def removeDuplicates(self, nums: List[int]) -> int:
head = 0
for i in range(len(nums)):
cur = nums[head]
if cur != nums[i]:
head+=1
nums[head] = nums[i]
return head+1
80 删除次数超过两次的重复项
拓展:保留k次
https://leetcode.cn/problems/remove-duplicates-from-sorted-array-ii/solutions/1/gong-shui-san-xie-guan-yu-shan-chu-you-x-glnq/?envType=study-plan-v2&envId=top-interview-150
169 找数组的众数
直接sort返回中间值lol
nums.sort()
return nums[int(len(nums) / 2)]