leetcode 关于重复问题和数组问题
目录
数组重复元素之类问题的整理
lt26 删除排序数组重复项
主要是原地删除,O(1) 空间,很是巧妙
func removeDuplicates(nums []int) int {
//O(1)空间复杂
if len(nums)==0{
return 0
}
tmp:=0
//不同,tmp+1,放在相应位置
for i:=1;i<len(nums);i++{
if nums[tmp]!=nums[i]{
tmp++
nums[tmp]=nums[i]
}
}
return tmp+1 //返回tmp+1 因为系统测评是最大下标在tmp
}
lt80 删除排序数组II
最多重复两次,空间O(1)
pos是已经放置的位置,放之前和2位前比较,确认不重复
func removeDuplicates(nums []int) int {
if len(nums)<3{
return len(nums)
}
pos:=2
//从2开始,
for i:=2;i<len(nums);i++{
if nums[i]!=nums[pos-2]{
nums[pos] = nums[i]
pos++
}
}
return pos
}
lt83 删除排序链表重复元素I
和排序数组类似,重复数字只保留一个
func deleteDuplicates(head *ListNode) *ListNode {
if head==nil||head.Next==nil{
return head
}
cur:=head
next:=head.Next
for next!=nil{
if cur.Val!=next.Val{
cur.Next = next
cur = cur.Next
}
next = next.Next
}
cur.Next = nil
return head
}
lt82 删除链表重复元素II
删除所有的重复元素
- 初始想法
重复元素放入map,然后再遍历时候删除
func deleteDuplicates(head *ListNode) *ListNode {
if head==nil||head.Next ==nil{
return head
}
//重复元素放置map中
hash:=make(map[int]int)
count:=0
pre:=head
cur:=head.Next
for cur!=nil{
if pre.Val==cur.Val{
count++
}else{
count=0
}
if count==1{
hash[cur.Val] = 1
}
pre = cur
cur = cur.Next
}
//找到对应的数删除
dummy:=new(ListNode)
dummy.Next = head
pre = dummy
cur = pre.Next
for cur!=nil{
if _,ok:=hash[cur.Val];ok{
pre.Next = cur.Next
cur = cur.Next
continue
}
pre = cur
cur = cur.Next
}
return dummy.Next
}
- 优化
一次遍历,加入flag判断是否有重复
func deleteDuplicates(head *ListNode) *ListNode {
if head==nil||head.Next ==nil{
return head
}
dummy:=new(ListNode)
dummy.Next = head
pre:=dummy
cur:=head
//一次性跳过所有重复元素
for cur!=nil{
flag:=false//标记有没有重复元素
for cur.Next!=nil&&cur.Val==cur.Next.Val{
cur = cur.Next
flag = true
}
if flag{ //有重复,cur.Next为不重复
pre.Next = cur.Next
}else{ //无重复,pre指向下一个
pre = cur
}
cur = cur.Next
}
return dummy.Next
}
lt217 存在重复元素I
判断是否存在重复元素
map一边判断一边加
func containsDuplicate(nums []int) bool {
//map即可
hash:=make(map[int]int)
for i:=0;i<len(nums);i++{
if _,ok:=hash[nums[i]];ok{
return true
}
hash[nums[i]]=1
}
return false
}
数组
4两个排序数组找中位数(要求时间复杂度O(m+n))
二分法
func findMedianSortedArrays(nums1 []int, nums2 []int) float64 {
size:=len(nums1)+len(nums2)
if size&1==1{
return float64(getK(nums1,nums2,size/2+1))
}else{
index1,index2:=size/2-1,size/2 //找到中间前面一点
//return float64((getK(nums1,nums2,index1+1)+getK(nums1,nums2,index2+1))/2.0) //如果先求和/2后再转换float,值不对
return float64(getK(nums1,nums2,index1+1)+getK(nums1,nums2,index2+1))/2.0 //加一符合函数中的找到下一个索引位置
}
}
func getK(nums1 []int,nums2 []int,k int)int{
index1,index2:=0,0
for {
if len(nums1)==index1{
return nums2[index2+k-1]
}
if len(nums2)==index2{
return nums1[index1+k-1]
}
if k==1{
return min(nums1[index1],nums2[index2])
}
half:=k/2
newindex1:=min(index1+half,len(nums1))-1 //找中点左边位置一个数
newindex2:=min(index2+half,len(nums2))-1
if nums1[newindex1]<=nums2[newindex2]{
k = k-(newindex1-index1+1) //防止越界减去太多
index1 = newindex1+1 //下一次的开始位置
}else{
k = k-(newindex2-index2+1)
index2 = newindex2+1
}
}
return 0
}
func min(x,y int)int{
if x>y{
return y
}else{
return x
}
}