【算法】15. 三数之和(多语言实现)

55 阅读3分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 20 天,点击查看活动详情


15. 三数之和:

给你一个整数数组 nums ,判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i != ji != kj != k ,同时还满足 nums[i] + nums[j] + nums[k] == 0 。请

你返回所有和为 0 且不重复的三元组。

注意:答案中不可以包含重复的三元组。

样例 1:

输入:
	nums = [-1,0,1,2,-1,-4]
	
输出:
	[[-1,-1,2],[-1,0,1]]
	
解释:
	nums[0] + nums[1] + nums[2] = (-1) + 0 + 1 = 0 。
	nums[1] + nums[2] + nums[4] = 0 + 1 + (-1) = 0 。
	nums[0] + nums[3] + nums[4] = (-1) + 2 + (-1) = 0 。
	不同的三元组是 [-1,0,1][-1,-1,2] 。
	注意,输出的顺序和三元组的顺序并不重要。

样例 2:

输入:
	nums = [0,1,1]
	
输出:
	[]
	
解释:
	唯一可能的三元组和不为 0 。
	

样例 3:

输入:
	nums = [0,0,0]
	
输出:
	[[0,0,0]]
	
解释:
	唯一可能的三元组和为 0

提示:

  • 3 <= nums.length <= 3000
  • -105 <= nums[i] <= 105

原题传送门:

leetcode.cn/problems/3s…


分析

  • 面对这道算法题目,二当家的陷入了沉思。
  • 第一反应就是暴力三层循环,但是据说会超时。
  • 如果是两数之和为0,在知道第一个数的情况下,第二个数也就固定了;
  • 三数之和在第一个数固定后,并不能固定第二个数和第三个数,所以才需要三层循环。
  • 然而如果我们把数组先排序一下,第二个数和第三个的位置就有了关系,第二个数越大,第三个数就要越小。
  • 排序后,我们还可以额外判断提前结束循环,要满足三数之和为0,第一个数一定是负数,第三个数一定是正数。

题解

rust

impl Solution {
    pub fn three_sum(mut nums: Vec<i32>) -> Vec<Vec<i32>> {
        let n = nums.len();
        nums.sort();
        let mut ans = Vec::new();
        (0..n).for_each(|f| {
            if f == 0 || nums[f] != nums[f - 1] {
                let mut t = n - 1;
                let target = -nums[f];
                for s in f + 1..n {
                    if s == f + 1 || nums[s] != nums[s - 1] {
                        while s < t && nums[s] + nums[t] > target {
                            t -= 1;
                        }
                        if s == t {
                            break;
                        }
                        if nums[s] + nums[t] == target {
                            ans.push(vec![nums[f], nums[s], nums[t]]);
                        }
                    }
                }
            }
        });
        return ans;
    }
}

go

func threeSum(nums []int) [][]int {
    n := len(nums)
    sort.Ints(nums)
    ans := make([][]int, 0)
    for f := 0; f < n; f++ {
        if f > 0 && nums[f] == nums[f-1] {
            continue
        }
        t := n - 1
        target := -1 * nums[f]
        for s := f + 1; s < n; s++ {
            if s > f+1 && nums[s] == nums[s-1] {
                continue
            }
            for s < t && nums[s]+nums[t] > target {
                t--
            }
            if s == t {
                break
            }
            if nums[s]+nums[t] == target {
                ans = append(ans, []int{nums[f], nums[s], nums[t]})
            }
        }
    }
    return ans
}

c++

class Solution {
public:
    vector<vector<int>> threeSum(vector<int>& nums) {
        int n = nums.size();
        sort(nums.begin(), nums.end());
        vector<vector<int>> ans;
        for (int f = 0; f < n; ++f) {
            if (f > 0 && nums[f] == nums[f - 1]) {
                continue;
            }
            int t = n - 1;
            int target = -nums[f];
            for (int s = f + 1; s < n; ++s) {
                if (s > f + 1 && nums[s] == nums[s - 1]) {
                    continue;
                }
                while (s < t && nums[s] + nums[t] > target) {
                    --t;
                }
                if (s == t) {
                    break;
                }
                if (nums[s] + nums[t] == target) {
                    ans.push_back({nums[f], nums[s], nums[t]});
                }
            }
        }
        return ans;
    }
};

java

class Solution {
    public List<List<Integer>> threeSum(int[] nums) {
        int n = nums.length;
        Arrays.sort(nums);
        List<List<Integer>> ans = new ArrayList<List<Integer>>();
        for (int f = 0; f < n; ++f) {
            if (f > 0 && nums[f] == nums[f - 1]) {
                continue;
            }
            int t      = n - 1;
            int target = -nums[f];
            for (int s = f + 1; s < n; ++s) {
                if (s > f + 1 && nums[s] == nums[s - 1]) {
                    continue;
                }
                while (s < t && nums[s] + nums[t] > target) {
                    --t;
                }
                if (s == t) {
                    break;
                }
                if (nums[s] + nums[t] == target) {
                    List<Integer> list = new ArrayList<Integer>();
                    list.add(nums[f]);
                    list.add(nums[s]);
                    list.add(nums[t]);
                    ans.add(list);
                }
            }
        }
        return ans;
    }
}

typescript

function threeSum(nums: number[]): number[][] {
    const n = nums.length;
    nums.sort((a, b) => a - b);
    const ans: number[][] = [];
    for (let f = 0; f < nums.length; ++f) {
        if (f > 0 && nums[f] === nums[f - 1]) {
            continue;
        }
        let t = n - 1;
        const target = -nums[f];
        for (let s = f + 1; s < n; ++s) {
            if (s > f + 1 && nums[s] == nums[s - 1]) {
                continue;
            }
            while (s < t && nums[s] + nums[t] > target) {
                --t;
            }
            if (s == t) {
                break;
            }
            if (nums[s] + nums[t] == target) {
                ans.push([nums[f], nums[s], nums[t]]);
            }
        }

    }
    return ans;
};

python

class Solution:
    def threeSum(self, nums: List[int]) -> List[List[int]]:
        n = len(nums)
        nums.sort()
        ans = list()
        for f in range(n):
            if f > 0 and nums[f] == nums[f - 1]:
                continue
            t = n - 1
            target = -nums[f]
            for s in range(f + 1, n):
                if s > f + 1 and nums[s] == nums[s - 1]:
                    continue
                while s < t and nums[s] + nums[t] > target:
                    t -= 1
                if s == t:
                    break
                if nums[s] + nums[t] == target:
                    ans.append([nums[f], nums[s], nums[t]])
        return ans


非常感谢你阅读本文~
放弃不难,但坚持一定很酷~
希望我们大家都能每天进步一点点~
本文由 二当家的白帽子:https://juejin.cn/user/2771185768884824/posts 博客原创~


开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 20 天,点击查看活动详情