日常系列LeetCode《13·综合应用1篇》
Posted 常某某的好奇心
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了日常系列LeetCode《13·综合应用1篇》相关的知识,希望对你有一定的参考价值。
数据规模->时间复杂度
<=10^4 😮(n^2)
<=10^7:o(nlogn)
<=10^8:o(n)
10^8<=:o(logn),o(1)
综合 <直接模拟、经典查找>
lc 1【top100】:两数之和
https://leetcode.cn/problems/two-sum/
提示:
2 <= nums.length <= 10^4
-10^9 <= nums[i] <= 10^9
-10^9 <= target <= 10^9
只会存在一个有效答案
进阶:
你可以想出一个时间复杂度小于 O(n^2) 的算法吗?
#方案一:线性查找
class Solution:
def twoSum(self, nums: List[int], target: int) -> List[int]:
#o(1),o(n^2)
for i in range(len(nums)):
for j in range(i+1,len(nums)):
if nums[i]+nums[j]==target:
return [i,j]
return -1
#方案二:排序二分查找->hash查找
class Solution:
def twoSum(self, nums: List[int], target: int) -> List[int]:
#o(n),o(2n)
#预处理
hashmap=
hashmap = x: i for i, x in enumerate(nums)
#
for i in range(len(nums)):
x=nums[i]
if target-x in hashmap:
j=hashmap[target-x]
if j!= i:
return [i,j]
return -1
#方案三:hash查找优化
class Solution:
def twoSum(self, nums: List[int], target: int) -> List[int]:
#o(n)
hashmap=
#o(n)
for i in range(len(nums)):
x=nums[i]
if target-x in hashmap:
j=hashmap[target-x]
#if j!= i: 不需要
return [i,j]
hashmap[nums[i]]=i
return -1
lc 167【剑指 006】:两数之和:输入有序数组
https://leetcode.cn/problems/two-sum-ii-input-array-is-sorted/
提示:
2 <= numbers.length <= 3 * 10^4
-1000 <= numbers[i] <= 1000
numbers 按 非递减顺序 排列
-1000 <= target <= 1000
仅存在一个有效答案
#方案一:二分查找法
class Solution:
def twoSum(self, numbers: List[int], target: int) -> List[int]:
n=len(numbers)
for i in range(n):
x=numbers[i]
#O(logn),O(1)
index=self.bi_search(numbers,i+1,n-1,target-x)
if index!=-1:return [i+1,index+1]#题目首位为1
return []
def bi_search(self,numbers,left,right,t):
while left<=right:
mid=left+(right-left)//2
if numbers[mid]==t:return mid
elif numbers[mid]>t:right=mid-1
else:left=mid+1
return -1
#方案二:双指针法
class Solution:
def twoSum(self, numbers: List[int], target: int) -> List[int]:
left,right=0,len(numbers)-1
#o(n),o(1)
while left<right:
s=numbers[left]+numbers[right]
if target==s:return [left+1,right+1]
elif target>s:left=left+1
else:right=right-1
return []
lc 170:两数之和:数据结构设计
https://leetcode.cn/problems/two-sum-iii-data-structure-design/
#方案一:二分查找
class TwoSum:
def __init__(self):
self.numbers=[]
self.is_sorted=False
def add(self, number: int) -> None:
self.numbers.append(number)
self.is_sorted=False
def find(self, value: int) -> bool:
#o(nlogn),o(n)
if not self.is_sorted:
self.numbers.sort()
self.is_sorted=True
#
left,right=0,len(self.numbers)-1
while left < right:
s = self.numbers[left] + self.numbers[right]
if s ==value:return True
elif s<value:left += 1
else:right -= 1
return False
# Your TwoSum object will be instantiated and called as such:
# obj = TwoSum()
# obj.add(number)
# param_2 = obj.find(value)
#方案二:hash查找
class TwoSum:
def __init__(self):
self.numbers=dict()
def add(self, number: int) -> None:
if number in self.numbers:self.numbers[number]+=1
else:self.numbers[number]=1
def find(self, value: int) -> bool:
#o(n),o(n)
for num in self.numbers.keys():
t=value-num
if t==num and self.numbers[t]>=2:return True
elif t!=num and t in self.numbers:return True
return False
# Your TwoSum object will be instantiated and called as such:
# obj = TwoSum()
# obj.add(number)
# param_2 = obj.find(value)
lc 653:两数之和:输入 BST
https://leetcode.cn/problems/two-sum-iv-input-is-a-bst/
提示:
二叉树的节点个数的范围是 [1, 10^4].
-10^4 <= Node.val <= 10^4
题目数据保证,输入的 root 是一棵 有效 的二叉搜索树
-10^5 <= k <= 10^5
#方案一:二分查找
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def findTarget(self, root: Optional[TreeNode], k: int) -> bool:
#o(n)
nums=[]
#中序遍历:o(n)
def inorder(node):
if not node:return
inorder(node.left)
nums.append(node.val)
inorder(node.right)
inorder(root)
#
left,right=0,len(nums)-1
while left<right:
s=nums[left]+nums[right]
if s==k:return True
elif s>k:right-=1
else:left+=1
return False
#方案二:一次遍历hash查找
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def findTarget(self, root: Optional[TreeNode], k: int) -> bool:
#o(n),o(n)
s=set()
#DFS
def find(node):
if not node:return False
if k-node.val in s:return True
s.add(node.val)
return find(node.left) or find(node.right) #key
return find(root) #return
lc 15【剑指 007】【top100】:三数之和
https://leetcode.cn/problems/3sum/
提示:
3 <= nums.length <= 3000
-10^5 <= nums[i] <= 10^5
#方案一:二分查找(去重技巧)
class Solution:
def threeSum(self, nums: List[int]) -> List[List[int]]:
#
nums.sort()
res=[]
#o(n^2)
for i in range(len(nums)-2):
#去重1
if i>=1 and nums[i]==nums[i-1]:continue
#
t=-nums[i]
left,right=i+1,len(nums)-1
while left<right:
s=nums[left]+nums[right]
if s==t:
res.append([nums[i],nums[left],nums[right]])
#去重2
#写法1
# while left < right:
# left = left + 1
# if nums[left - 1] != nums[left]: break
# while left < right:
# right = right - 1
# if nums[right + 1] != nums[right]: break
#写法2
while left<right and nums[left]==nums[left+1]:left+=1
left+=1
while left<right and nums[right]==nums[right-1]:right-=1
right-1
#
elif s>t:right-=1
else:left+=1
return res
lc 18 :四数之和
https://leetcode.cn/problems/4sum/
提示:
1 <= nums.length <= 200
-10^9 <= nums[i] <= 10^9
-10^9 <= target <= 10^9
class Solution:
def fourSum(self, nums: List[int], target: int) -> List[List[int]]:
#
nums.sort()
res = []
#o(n^3)
for i in range(len(nums) - 3):
#去重1
if i>=1 and nums[i]==nums[i-1]:continue
for j in range(i+1,len(nums)-2):
#去重2
if j>=i+2 and nums[j]==nums[j-1]:continue
#
s1=nums[i]+nums[j]
left,right=j+1,len(nums)-1
while left<right:
s=s1+nums[left]+nums[right]
if s==target:
res.append([nums[i],nums[j],nums[left],nums[right]])
#去重3
while left<right and nums[left]==nums[left+1]:left+=1
left+=1
while left<right and nums[right]==nums[right-1]:right-=1
right-=1
elif s>target:
right-=1
else:left+=1
return res
lc 349 : 两个数组的交集
https://leetcode.cn/problems/intersection-of-two-arrays/
提示:【去重】
1 <= nums1.length, nums2.length <= 1000
0 <= nums1[i], nums2[i] <= 1000
#方案一:线性查找
class Solution:
def intersection(self, nums1: List[int], nums2: List[int]) -> List[int]:
#o(m*n),o(min(m,n))
res=set()
for n1 in nums1:
for n2 in nums2:
if n1==n2:
res.add(n1)
return list(res) #key
#方案二:二分查找
class Solution:
def intersection(self, nums1: List[int], nums2: List[int]) -> List[int]:
#o(nlogn+mlogn),o(min(m,n))
res=set()
nums2.sort() #nlogn
for n1 in nums1:
#o(logn)
if self.contain(nums2,n1):
res.add(n1)
return list(res) #key
def contain(self,nums,t):
left,right=0,len(nums)-1
while left<=right:
mid=left+(right-left)//2
if nums[mid]==t:return True
elif nums[mid]>t:right=mid-1
else:left=mid+1
return False
#方案三:hash查找
class Solution:
def intersection(self, nums1: List[int], nums2: List[int]) -> List[int]:
#o(n+m),o(min(m,n)+n)
res=set()#o(min(m,n))
set2=set(nums2) #o(n),o(n)
#o(m)
for n1 in nums1:
#o(1)
if n1 in set2:
res.add(n1)
#
return list(res)
#方案四:双指针排序去重
class Solution:
def intersection(self, nums1: List[int], nums2: List[int]) -> List[int]:
#o(nlogn+mlogm),o(min(m,n))
res=[]
nums1.sort()
nums2.sort()
#
i=j=0
while i<len(nums1) and j<len(nums2):
if nums1[i]==nums2[j]:
if len(res)==0 or nums1[i]!=res[-1]:
res.append(nums1[i])
#注:位置
i+=1
j+=1
elif nums1[i]>nums2[j]:
j+=1
else:i+=1
return res
lc 350 :两个数组的交集 II
https://leetcode.cn/problems/intersection-of-two-arrays-ii/
提示:【不去重】
1 <= nums1.length, nums2.length <= 1000
0 <= nums1[i], nums2[i] <= 1000
进阶:
如果给定的数组已经排好序呢?你将如何优化你的算法?
如果 nums1 的大小比 nums2 小,哪种方法更优?
如果 nums2 的元素存储在磁盘上,内存是有限的,并且你不能一次加载所有的元素到内存中,你该怎么办?
#方案一:哈希查找
class Solution:
def intersect(self, nums1: List[int], nums2: List[int]) -> List[int]:
#o(min(m,n)+n),o(m+n)
res=[]
map1=num:0 for num in nums1
for num in nums1:map1[num]+=1
#
for n in nums2:
if n in map1 and map1.get(n)>0:
res.append(n)
map1[n]-=1
#
return res
#方案二:二分查找
cl以上是关于日常系列LeetCode《13·综合应用1篇》的主要内容,如果未能解决你的问题,请参考以下文章