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

举报
二当家的白帽子 发表于 2024/04/25 10:54:55 2024/04/25
【摘要】 15. 三数之和:给你一个整数数组 nums ,判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i != j、i != k 且 j != k ,同时还满足 nums[i] + nums[j] + nums[k] == 0 。请你返回所有和为 0 且不重复的三元组。注意:答案中不可以包含重复的三元组。 样例 1:输入: nums = [-1,0,1,2,-1...

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

分析

  • 面对这道算法题目,二当家的陷入了沉思。
  • 第一反应就是暴力三层循环,但是据说会超时。
  • 如果是两数之和为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://bbs.huaweicloud.com/community/usersnew/id_1628396583336561 博客原创~


【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。