Leetcode日练笔记11 #350 #167 Intersection of Two Arrays II & Two Sum II - Input array is sorted

#350 Intersection of Two Arrays II

Given two integer arrays nums1 and nums2, return an array of their intersection. Each element in the result must appear as many times as it shows in both arrays and you may return the result in any order.

解题思路:

还是用回之前的办法,先求得两个list的intersection。然后for循环每个intersection里的元素,取元素在两个list出现次数的最小值,然后在最后result补齐该元素出现的次数。

class Solution:
    def intersect(self, nums1: List[int], nums2: List[int]) -> List[int]:
        sml_num = min(len(nums1), len(nums2))
        if sml_num == len(nums1):
            intersection =  set(nums2).intersection(nums1)
        else:
            intersection = set(nums1).intersection(nums2)
        
        result = []
        for i in intersection:
            occurrence = min(nums1.count(i), nums2.count(i))
            for j in range(occurrence):
                result.append(i)
        return result
                

runtime:

Leetcode日练笔记11 #350 #167 Intersection of Two Arrays II & Two Sum II - Input array is sorted_第1张图片

但这样很慢……

然后想起有种更快多次添加同个元素的办法。不用for,直接 [添加元素] * 添加次数。

class Solution:
    def intersect(self, nums1: List[int], nums2: List[int]) -> List[int]:
        if len(nums1) < len(nums2):
            intersection =  set(nums2).intersection(nums1)
        else:
            intersection = set(nums1).intersection(nums2)
        
        result = []
        for i in intersection:
            occurrence = min(nums1.count(i), nums2.count(i))
            result += [i]*occurrence
        return result
                

这样快多了。

Leetcode日练笔记11 #350 #167 Intersection of Two Arrays II & Two Sum II - Input array is sorted_第2张图片

 sample solution给的是java和c++。暂时看不懂,只能等学了这两种语言再把题做一遍了。

#167 Two Sum II - Input array is sorted

Given a 1-indexed array of integers numbers that is already sorted in non-decreasing order, find two numbers such that they add up to a specific target number. Let these two numbers be numbers[index1] and numbers[index2] where 1 <= index1 < index2 <= numbers.length.

Return the indices of the two numbers, index1 and index2added by one as an integer array [index1, index2] of length 2.

The tests are generated such that there is exactly one solution. You may not use the same element twice.

Your solution must use only constant extra space.

解题思路:

因为一定有一对解。所以就for把list的元素过一遍,直到找到解为止。

过的时候,用target减去当前元素,然后在剩下的元素看这个差值存不存在。在就把当前这个元素的idx1,和差值的idx2输出了。(按题目设置一定有对解,所以总会找到存在的差值)。

棘手的是差值和当前元素相等,idx1和idx2会冲突。index()第一个argument是要确定index的值,第二个argument是optional的,是寻找的起始位置。用这个办法区分开来idx1和idx2。

class Solution:
    def twoSum(self, numbers: List[int], target: int) -> List[int]:
        idx1 = 0
        for i in numbers:
            num = target - i
            if num == i:
                if num in numbers[numbers.index(i)+1:]:
                    idx2 = numbers.index(num, numbers.index(i)+1)
                    return [idx1+1, idx2+1]
            else:
                if num in numbers: 
                    idx2 = numbers.index(num)
                    return [idx1+1, idx2+1]
            idx1 += 1

可是time limit exceeded……

谷歌查了下,说in operator as List containment 时是 O(n)。这就是慢的原因。如果是Dict lookup就是O(1)。

所以不能用if in的办法确认差值存不存在以及其index。只能用二分搜索法。

class Solution:
    def twoSum(self, numbers: List[int], target: int) -> List[int]:
        idx1,idx2 = 0, 0
        for i in numbers:
            num = target - i
            l, r = idx1+1, len(numbers)-1
            while l < r:
                m = (l+r)//2
                if num > numbers[m]:
                    l = m + 1
                elif num < numbers[m]:
                    r = m
                else:
                    if num == i:
                        idx2 = numbers.index(num, idx1+1)
                    else:
                        idx2 = numbers.index(num)
                    break
            if idx2:
                return [idx1+1, idx2+1]
            if numbers[l] == num:
                if num == i:
                    idx2 = numbers.index(num, idx1+1)
                else:
                    idx2 = numbers.index(num)
                return [idx1+1, idx2+1]
            idx1 += 1

runtime:

Leetcode日练笔记11 #350 #167 Intersection of Two Arrays II & Two Sum II - Input array is sorted_第3张图片

还是很慢……

44ms的solution:Leetcode日练笔记11 #350 #167 Intersection of Two Arrays II & Two Sum II - Input array is sorted_第4张图片

两指针的和大于target就右指针左移,小于target就左指针右移。直到遇到解为止。好妙。

重新写了一遍:

class Solution:
    def twoSum(self, numbers: List[int], target: int) -> List[int]:
        l, r = 0, len(numbers)-1
        while l < r:
            val = numbers[l] + numbers[r]   
            if val < target:
                l += 1
            elif val > target:
                r -= 1
            else:
                return [l+1, r+1]

玄学runtime:

Leetcode日练笔记11 #350 #167 Intersection of Two Arrays II & Two Sum II - Input array is sorted_第5张图片

你可能感兴趣的:(leetcode日练,leetcode,算法,python)