• 算法leetcode|15. 三数之和(rust重拳出击)




    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] 。
    	注意,输出的顺序和三元组的顺序并不重要。
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    样例 2:

    输入:
    	nums = [0,1,1]
    	
    输出:
    	[]
    	
    解释:
    	唯一可能的三元组和不为 0 。
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    样例 3:

    输入:
    	nums = [0,0,0]
    	
    输出:
    	[[0,0,0]]
    	
    解释:
    	唯一可能的三元组和为 0 。
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    提示:

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

    原题传送门:

    https://leetcode.cn/problems/3sum/


    分析

    • 面对这道算法题目,二当家的陷入了沉思。
    • 第一反应就是暴力三层循环,但是据说会超时。
    • 如果是两数之和为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;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    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
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    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;
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    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;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33

    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;
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    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
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    非常感谢你阅读本文~
    欢迎【点赞】【收藏】【评论】~
    放弃不难,但坚持一定很酷~
    希望我们大家都能每天进步一点点~
    本文由 二当家的白帽子:https://le-yi.blog.csdn.net/ 博客原创~


  • 相关阅读:
    蓝桥杯国赛算法复习
    ShareSDK 第三方平台分享参数说明
    Kubernetes(k8s)是什么?解决了哪些问题?
    【Git】:初识git
    代理IP和Socks5代理:跨界电商与全球爬虫的关键技术
    Linux服务器安装配置Redis
    通过SpringCloudGateway中的GlobalFilter实现鉴权过滤
    python 移动测试之Appium环境搭建及简单应用
    Type-C接口相关知识
    api-ms-win-crt-runtime-l1-1-0.dll文件加载失败是怎么造成的?怎么修复?
  • 原文地址:https://blog.csdn.net/leyi520/article/details/127901395