1. Topic description
Given two ordered (increasing) integer arraysnums1
andnums2
, please return the intersection of the two arrays in array form,M
is a longer length array ,N
is the shorter array length. E.g:
Given:nums1 = [1,2,3,4,5,6]
,nums2 = [1,2,3]
Output:[1,2,3]
This problem is common and not difficult. The interesting thing is that there are many solutions. In the scenarios ofnums1
andnums2
, choose the most efficient solution.
2. Hash table
This is the easiest solution to think of, hash the shorter array and traverse the longer array to get the intersection
function intersect(nums1, nums2){
let hash = new Set()//这里用set来代表哈希,他们本质是一样的
for (let i = 0; i < nums2.length; i++) {
hash.add(nums2[i])
}
for (let i = 0; i < nums1.length; i++) {
if (hash.has(nums1[i])) {
ans.push(nums1[i])
}
}
return ans
}
Time complexity: O(M+N)
<br/>
Space complexity: hashed for shorter arrays, O(N)
3. Binary search
Thinking about a scenario, the long array is very long, and the solution of the hash table is linear. Obviously, the condition of the array order is not well utilized. At this time, the binary search stands out, because the greater the difference between the two lengths, the higher the binary efficiency. ;
function intersect(nums1, nums2){
//由于是递增,定义一个left,稍微减少下查找范围
let left = 0;
for (let i = 0; i < nums2.length; i++) {
//二分查找
let index = binarySearch(nums1, nums2[i], left)
if (index != -1) {
ans.push(nums2[i])
left = index + 1
}
}
return ans
}
function binarySearch(nums, target, left = 0, right = nums.length - 1){
//特殊处理 端点的情况 可以加速连续数组的查找
if(nums[left] == target){
return left
}
if(nums[right] == target){
return right
}
while(left <= right){
mid = Math.floor((left + right)/2)
if (nums[mid] == target) {
return mid
}else if(nums[mid] > target){
right = mid - 1
}else{
left = mid + 1
}
}
return -1
}
Here we focus on why we should optimize the left starting point of binary search. If we do not give the left starting point, then each binary point is from0
tolen -1
binary, and because the array has In order, if you have foundnum1
intarget
, then the next one to be foundtarget
must be located in the previoustarget
of 95ebcd7---4ac3599 to the right, thus avoiding the binary search every time from0
began, under the best circumstances such asnums1 = [1,2,3,4,5,6]
,nums2 = [4,5,6]
, first find4
remaining5
,6
apparently4
the right, as long as the actualO(N)
times to be a time complexity:M
for longer array length,N
for shorter array length, worst/average complexityO(N*logM)
, and since we optimized the left starting point for binary search , in the most ideal case the complexity can reachO(N)
; not ideally, the time complexity depends on the distribution of the intersection innums1
, the intersection innums1
The more right the middle is distributed, the higher the search efficiency is<br/>
Space complexity: if the recursive array is a reference, we only use constant-level variable spaceO(1)
4. Double pointer
If the lengths of the two arrays are not much different, then double pointers are obviously more efficient;
function intersect(nums1, nums2){
let m = n = 0
while( m < nums1.length && n < nums2.length ) {
if (nums1[m] == nums2[n]) {
ans.push(nums1[m])
m++
n++
}else if (nums1[m] > nums2[n]) {
n++
}else{
m++
}
}
return ans
}
Time complexity: M
is longer array length, N
is shorter array length, the best case is O(N)
, the worst case is O(M)
<br/>
Space complexity: only constant-level variable space is used O(1)
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。