[python]LeetCode_167. Two Sum II - Input Array Is Sorted

本文介绍了LeetCode 167题的解决方案,即在一个已排序的非递减数组中找到两个数,使它们的和等于目标值。首先尝试了遍历查找的直觉解法,但发现时间复杂度过高。然后利用数组已排序的特性,采用双指针法,从两端向中间逼近,显著降低了时间复杂度到O(N)。这种方法避免了无效计算,提高了效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

[python]LeetCode_167. Two Sum II - Input Array Is Sorted



牽涉概念及時間紀錄

20220408 17:08-17:20 for 第一次
使用雙指針方式能降低時間複雜度
當需要雙迴圈時可以往此方向考慮


一、題目內容

簡而言之:

就是給定一個list 裡面有很多數字,以及一個目標數字。
請找出其中哪兩數字相加之後會與目標數字吻合。
必有唯一解,且同一位置不重複使用(ex 不會有[2,2]這種答案)

以下題目原文:

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 index2, 
added 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.

Example 1:

Input: numbers = [2,7,11,15], target = 9
Output: [1,2]
Explanation: The sum of 2 and 7 is 9. Therefore, index1 = 1, index2 = 2. We return [1, 2].

Example 2:

Input: numbers = [2,3,4], target = 6
Output: [1,3]
Explanation: The sum of 2 and 4 is 6. Therefore index1 = 1, index2 = 3. We return [1, 3].

Example 3:

Input: numbers = [-1,0], target = -1
Output: [1,2]
Explanation: The sum of -1 and 0 is -1. Therefore index1 = 1, index2 = 2. We return [1, 2].

Constraints:

2 <= numbers.length <= 3 * 104
-1000 <= numbers[i] <= 1000
numbers is sorted in non-decreasing order.
-1000 <= target <= 1000
The tests are generated such that there is exactly one solution.

二、想法思路

1.直觀想法:

一開始不假思索就是遍歷查找一遍就應該有答案了?
fish yes (於是,抱歉我突然想耍白痴一下XD)
就直接使用迴圈從頭開始找,並注意一些可能造成無效計算的情況。
諸如相同的重複字元(ex 0,0,0,1,2,3 這樣的)
時間複雜度為O(N^2)
空間複雜度為O(1).

def twoSum(self, numbers: List[int], target: int) -> List[int]:
        numbers_l = len(numbers)
        for num in range(numbers_l):
            if num > 0:
            	# ignore same number that has already calculate.
                if numbers[num] == numbers[num-1]:
                    continue
            for num_in in range(num+1, numbers_l):
                if target == numbers[num] + numbers[num_in]:
                    return [num+1, num_in+1]
                elif target < numbers[num] + numbers[num_in]:
                    break

2.想想發現不太對,優化一下:

這邊由於題目已經明確說明是non-decreasing order了,
用指標的想法去做,可以將時間降低不少.
一開始將指標指在最小與最大,逐步往中間靠攏即可找到符合的答案。
時間複雜度為O(N)
空間複雜度為O(1).

def twoSum(self, numbers: List[int], target: int) -> List[int]:
        numbers_l = len(numbers)
        # little is the less pointer, and the big is the large pointer
        little = 0
        big = numbers_l-1
        while numbers[little] + numbers[big] != target:
            if numbers[little] + numbers[big] > target:
                big -= 1
                while numbers[big] == numbers[big-1] and numbers[little] + numbers[big] > target:
                    big -= 1
            else:
                little += 1
                while numbers[little] == numbers[little+1] and numbers[little] + numbers[big] < target:
                    little +=1
        return [little+1, big+1]

总结

這題第一種應該大部分人都會直覺想到這樣做,畢竟暴力解始終是種解。
但不知道是否我哪裡沒有寫好,兩種作法在leetcode上的時間幾乎一樣。
如果有知道哪裡有問題的大神,麻煩告訴我一下。
感謝花時間看到這裡的大家。

如果有錯,請不吝告知,也可以一起討論,一起加油XD

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值