[數(shù)組]N數(shù)之和問題

leetcode_1. 兩數(shù)之和

題目描述

給定一個(gè)整數(shù)數(shù)組 nums 和一個(gè)目標(biāo)值 target,請你在該數(shù)組中找出和為目標(biāo)值的那 兩個(gè) 整數(shù),并返回他們的數(shù)組下標(biāo)。
你可以假設(shè)每種輸入只會對應(yīng)一個(gè)答案。但是,你不能重復(fù)利用這個(gè)數(shù)組中同樣的元素。

示例:
給定 nums = [2, 7, 11, 15], target = 9

因?yàn)?nums[0] + nums[1] = 2 + 7 = 9
所以返回 [0, 1]

來源:力扣(LeetCode)
鏈接:https://leetcode-cn.com/problems/two-sum

解題思路

利用哈希表,在迭代中判斷是否存在target-nums[i]這一元素,然后將tmp和其索引存入哈希表中

在python中可以用字典表示哈希表

代碼實(shí)現(xiàn)

class Solution(object):
    def twoSum(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: List[int]
        """
        ans_map = dict()
        for i in range(0, len(nums)):  # 一邊將列表中的數(shù)添加到字典中,一邊判斷兩數(shù)之差是否存在于字典中
            temp = target - nums[i]
            if temp in ans_map:  # 判斷步驟
                return [ans_map[temp], i]
            ans_map[nums[i]] = i  # 添加步驟(切記先判斷再添加,以免key沖突)

注意:此題不適合使用雙指針,因?yàn)樾枰葘?shù)組進(jìn)行排序,而排序后,數(shù)組的下標(biāo)會被打亂,結(jié)果要求返回的數(shù)字的下標(biāo)

leetcode_15. 三數(shù)之和

題目描述

給定一個(gè)包含 n 個(gè)整數(shù)的數(shù)組 nums,判斷 nums 中是否存在三個(gè)元素 a,b,c ,使得 a + b + c = 0 ?找出所有滿足條件且不重復(fù)的三元組。

注意:答案中不可以包含重復(fù)的三元組。

示例:

給定數(shù)組 nums = [-1, 0, 1, 2, -1, -4],

滿足要求的三元組集合為:
[
[-1, 0, 1],
[-1, -1, 2]
]

來源:力扣(LeetCode)
鏈接:https://dev.lingkou.xyz/problems/3sum

解題思路

  1. 將數(shù)組排序
  2. 定義指針i,left,right。遍歷i,將問題轉(zhuǎn)化為在i之后的數(shù)組中尋找nums[i]+nums[left]+nums[right]=0的問題(即三數(shù)之和可以使用雙指針解決)
  3. 剪枝,去重

代碼實(shí)現(xiàn)

# 雙指針,所以先固定一個(gè)數(shù)字,用雙指針來找到另外兩個(gè)數(shù)字。注意記得剪枝
class Solution(object):
    def threeSum(self, nums):
        """
        :type nums: List[int]
        :rtype: List[List[int]]
        """
        rnums=[]              # 創(chuàng)建一個(gè)要返回的新列表
        nums.sort()       # 排序
        n = len(nums)
        for i in range(n):
            if i > 0 and nums[i] == nums[i-1]: # 避免重復(fù)項(xiàng)
                  continue
            if nums[i] > 0:# 減少無關(guān)計(jì)算,定值大于 0 后,后面的都大于 0,沒必要進(jìn)行計(jì)算了
                break
            left = i + 1
            right = n -1
            while left < right:    
                cur_num = nums[i] + nums[left] + nums[right]
                if cur_num == 0:
                    tmp = [nums[i], nums[left], nums[right]]
                    rnums.append(tmp)
                    while left < right and nums[left]==nums[left+1]: # 去重
                        left += 1
                    while left < right  and nums[right]==nums[right-1]: # 去重
                        right -= 1
                    left += 1
                    right -= 1
                elif cur_num > 0:
                    right -= 1
                else:
                    left += 1
        return rnums

leetcode_16. 最接近的三數(shù)之和

題目描述

給定一個(gè)包括 n 個(gè)整數(shù)的數(shù)組 nums 和 一個(gè)目標(biāo)值 target。找出 nums 中的三個(gè)整數(shù),使得它們的和與 target 最接近。返回這三個(gè)數(shù)的和。假定每組輸入只存在唯一答案。

例如,給定數(shù)組 nums = [-1,2,1,-4], 和 target = 1.

與 target 最接近的三個(gè)數(shù)的和為 2. (-1 + 2 + 1 = 2).

來源:力扣(LeetCode)
鏈接:https://dev.lingkou.xyz/problems/3sum-closest

解題思路

  1. 若數(shù)組長度小于3,返回[]
  2. 排序數(shù)組
  3. 遍歷數(shù)組
    1. 跳過重復(fù)元素
    2. 設(shè)置左指針left和右指針right,當(dāng)left < right 時(shí),循環(huán)
      1. get_nums = nums[i] + nums[left] + nums[right], 如果get_nums = target ,返回target
      2. 若abs(get_nums - target) < abs(res - target) 說明get_nums更靠近目標(biāo),更新res
      3. 剪枝
  4. 返回結(jié)果

代碼實(shí)現(xiàn)

class Solution(object):
    def threeSumClosest(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: int
        """
        if not nums or len(nums) < 3:  # 排除特殊情況
            return None
        nums.sort()
        res = float("inf")  # py用來表示正無窮
        for i in range(len(nums)):
            if i > 0 and nums[i] == nums[i - 1]:    # 去重,提高效率
                continue
            left = i + 1
            right = len(nums) - 1
            while left < right:
                get_nums = nums[i] + nums[left] + nums[right]
                if get_nums == target:
                    return target
                if abs(get_nums - target) < abs(res - target):  # 說明get_nums更靠近目標(biāo)
                    res = get_nums  # 更新內(nèi)容
                if get_nums - target < 0:
                    left += 1
                else:
                    right -= 1
        return res

leetcode_18. 四數(shù)之和

題目描述

給定一個(gè)包含 n 個(gè)整數(shù)的數(shù)組 nums 和一個(gè)目標(biāo)值 target,判斷 nums 中是否存在四個(gè)元素 a,b,c 和 d ,使得 a + b + c + d 的值與 target 相等?找出所有滿足條件且不重復(fù)的四元組。

注意:

答案中不可以包含重復(fù)的四元組。

示例:

給定數(shù)組 nums = [1, 0, -1, 0, -2, 2],和 target = 0。

滿足要求的四元組集合為:
[
[-1, 0, 0, 1],
[-2, -1, 1, 2],
[-2, 0, 0, 2]
]

來源:力扣(LeetCode)
鏈接:https://leetcode-cn.com/problems/4sum

解題思路

  1. 排序
  2. 使用雙循環(huán)固定兩個(gè)數(shù),用雙指針尋找另外兩個(gè)數(shù),通過比較target大小,移動(dòng)指針
  3. 剪枝,去重

代碼實(shí)現(xiàn)

class Solution(object):
    def fourSum(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: List[List[int]]
        """
        res = []
        nums.sort()
        n = len(nums)
        for a in range(n - 3):
            # 防止重復(fù)
            if a > 0 and nums[a] == nums[a - 1]:
                continue
            # 當(dāng)最小值和都大于target, 跳出
            if nums[a] + nums[a + 1] + nums[a + 2] + nums[a + 3] > target:
                break
            # 數(shù)組最大值和小于target, 就遍歷下一個(gè)
            if nums[a] + nums[n - 1] + nums[n - 2] + nums[n - 3] < target:
                continue
            for b in range(a + 1, n - 2):
                # 防止重復(fù)
                if b - a > 1 and nums[b] == nums[b - 1]:
                    continue
                if nums[a] + nums[b] + nums[b + 1] + nums[b + 2] > target:
                    break
                if nums[a] + nums[b] + nums[n - 1] + nums[n - 2] < target:
                    continue
                # 雙指針
                left = b + 1
                right = n - 1
                while left < right:
                    tmp = nums[a] + nums[b] + nums[left] + nums[right]
                    if tmp == target:
                        res.append([nums[a], nums[b], nums[left], nums[right]])
                        while left < right and nums[left] == nums[left+1]:
                            left += 1
                        while left < right and nums[right] == nums[right-1]:
                            right -= 1
                        left += 1
                        right -= 1
                    elif tmp > target:
                        right -= 1
                    else:
                        left += 1
        return res
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 1. leetcode-1 兩數(shù)之和 1.1 題目描述 給定一個(gè)整數(shù)數(shù)組 nums 和一個(gè)目標(biāo)值 target,請...
    一只可愛的檸檬樹閱讀 733評論 0 0
  • 描述:給定一個(gè)包括n 個(gè)整數(shù)的數(shù)組nums和 一個(gè)目標(biāo)值target。找出nums中的三個(gè)整數(shù),使得它們的和與ta...
    暖男Gatsby閱讀 235評論 0 0
  • 動(dòng)態(tài)規(guī)劃 111. 爬樓梯思路類似斐波那契數(shù)列注意考慮第 0 階的特殊情況 272. 爬樓梯 II思路類似上題,只...
    6默默Welsh閱讀 2,618評論 0 1
  • 算法思想 一、二分查找 1. 算法思想 算法詳解 算法細(xì)節(jié) 一定要看二分查找細(xì)節(jié).md 實(shí)現(xiàn)時(shí)需要注意以下細(xì)節(jié): ...
    因丶為閱讀 482評論 0 0
  • 給定一個(gè)整數(shù)數(shù)組 nums和一個(gè)目標(biāo)值 target,請你在該數(shù)組中找出和為目標(biāo)值的那兩個(gè)整數(shù),并返回他們的數(shù)組下...
    三沐寶閱讀 244評論 0 0

友情鏈接更多精彩內(nèi)容