LeetCode 15. 三數(shù)之和(3Sum)

LeetCode.jpg

三數(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]
]

Python3實(shí)現(xiàn)

借助兩數(shù)之和

# @author:leacoder
# @des:   借助兩數(shù)之和  三數(shù)之和

class Solution(object):
    def threeSum(self, nums):
        nums.sort() #排序 方便去重
        res = []
        for i, num in enumerate(nums): #一層循環(huán)
            if i > 0 and nums[i] == nums[i-1]: # 避免重復(fù)
                continue
                
            new_nums = nums[i+1:] #剔除 一層循環(huán)后的數(shù) 
            two_sums = self.twoSum(new_nums, -num) #由于何為0  兩數(shù)之和要為 -num
            for two_sum in two_sums:
                res.append([num, new_nums[two_sum[0]], new_nums[two_sum[1]]])
                         
        return res
            
        
    def twoSum(self, nums, target):
        d = {}
        res = []
        hit = False
        for i, num in enumerate(nums):
            if i > 1 and nums[i] == nums[i-1] and hit:
                continue
            if num in d:
                res.append([d[num], i])
                hit = True
            else:
                d[target - num] = i
                hit = False
        return res

一層枚舉 左右兩指針形式

# @author:leacoder
# @des:   一層枚舉 左右兩指針形式  三數(shù)之和 

class Solution:
    def threeSum(self, nums: List[int]) -> List[List[int]]:
        res = []
        nums.sort()
        for index1,value in enumerate(nums[:-2]): #一層循環(huán)
            if index1>0 and nums[index1] == nums[index1-1]: #不可以包含重復(fù)的三元組
                continue
            left,right = index1+1,len(nums)-1  #左右指針形式  左:一層數(shù)據(jù)右側(cè)開(kāi)始  右:數(shù)據(jù)最右端開(kāi)始
            while left<right: #循環(huán)條件  依據(jù)實(shí)際大小情況,選擇左或右指針向中間移動(dòng)  但右必定大于左
                sumtmp = nums[index1] + nums[left] + nums[right] #三數(shù)和
                if sumtmp <0: left +=1 # <0 表明和小了,那么左指針向右+1 真大 nums[left]  nums已經(jīng)排序 右邊必定大于 左邊
                elif sumtmp >0: right -=1 #同上 
                else: #剛好為0
                    res.append((nums[index1],nums[left],nums[right]))
                    while left < right and nums[left]==nums[left+1]: #不可以包含重復(fù)的三元組
                        left +=1
                    while left < right and nums[right]==nums[right-1]:#不可以包含重復(fù)的三元組
                        right -=1
                    left +=1;right -=1
        return res
                

C++實(shí)現(xiàn)

一層枚舉 左右兩指針形式

/*
 *@author:leacoder
 *@des:   一層枚舉 左右兩指針形式  三數(shù)之和 
 */
class Solution {
public:
    vector<vector<int>> threeSum(vector<int>& nums) {
        vector<vector<int>> res; //返回值
        if(nums.size()<3){ //輸入檢查
            return res;
        }
        sort(nums.begin(), nums.end()); //排序
        
        for (int i = 0; i < nums.size()-2; i++) //一層循環(huán)
        {
            if(i>0 && nums[i] == nums[i-1])
                continue;
            int target = -nums[i]; //其他兩數(shù)和
            int l = i + 1, r = nums.size() - 1; //左右指針形式  l 左 r右
            while (l < r)
            {
                if (nums[l] + nums[r] < target) //小于目標(biāo) l 增加
                    ++l;
                else if (nums[l] + nums[r] > target) //大于目標(biāo) r 減少
                    --r;
                else{ //剛好
                    res.push_back(vector<int>{nums[i], nums[l], nums[r]});
                    while (l < r && nums[l] == nums[l+1])
                        l++;
                    while (l < r && nums[r] == nums[r-1])
                        r--;
                    l++; r--;
                }
            }
            
        }
        return res;
    }
};

GitHub鏈接:
https://github.com/lichangke/LeetCode
知乎個(gè)人首頁(yè):
https://www.zhihu.com/people/lichangke/
個(gè)人Blog:
https://lichangke.github.io/
歡迎大家來(lái)一起交流學(xué)習(xí)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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