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

简介: 给你一个整数数组 nums ,判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i != j、i != k 且 j != k ,同时还满足 nums[i] + nums[j] + nums[k] == 0 。请你返回所有和为 0 且不重复的三元组。注意:答案中不可以包含重复的三元组。

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://developer.aliyun.com/profile/sqd6avc7qgj7y 博客原创~


相关文章
|
2月前
|
自然语言处理 Rust 算法
【算法】13. 罗马数字转整数(多语言实现)
罗马数字包含以下七种字符: I, V, X, L,C,D 和 M。 | 字符 | 数值 | |--|--| | I | 1 | | V | 5 | | X | 10 | | L | 50 | | C | 100 | | D | 500 | | M | 1000 | 例如, 罗马数字 2 写做 II ,即为两个并列的 1。12 写做 XII ,即为 X + II 。 27 写做 XXVII, 即为 XX + V + II 。 通常情况下,罗马数字中小的数字在大的数字的右边。但也存在特例,例如 4 不写做 IIII,而是 IV。数字 1 在数字 5 的左边,所表示的数等于大数 5 减小数 1
【算法】13. 罗马数字转整数(多语言实现)
|
9月前
|
自然语言处理 Rust 算法
【算法】9. 回文数(多语言实现)
给你一个整数 x ,如果 x 是一个回文整数,返回 true ;否则,返回 false 。 回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数。例如,121 是回文,而 123 不是。
|
4天前
|
自然语言处理 Rust 算法
【算法】17. 电话号码的字母组合(多语言实现)
给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。答案可以按 任意顺序 返回。 给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。
【算法】17. 电话号码的字母组合(多语言实现)
|
1月前
|
算法 自然语言处理 Rust
【算法】16. 最接近的三数之和(多语言实现)
给你一个长度为 n 的整数数组 nums 和 一个目标值 target。请你从 nums 中选出三个整数,使它们的和与 target 最接近。 返回这三个数的和。 假定每组输入只存在恰好一个解。
|
2月前
|
自然语言处理 Rust 算法
【算法】14. 最长公共前缀(多语言实现)
编写一个函数来查找字符串数组中的最长公共前缀。 如果不存在公共前缀,返回空字符串 ""。
|
2月前
|
自然语言处理 Rust 算法
【算法】11. 盛最多水的容器(多语言实现)
给定一个长度为 n 的整数数组 height 。有 n 条垂线,第 i 条线的两个端点是 (i, 0) 和 (i, height[i]) 。 找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。 返回容器可以储存的最大水量。 说明: 你不能倾斜容器。
【算法】11. 盛最多水的容器(多语言实现)
|
2月前
|
自然语言处理 Rust 算法
【算法】12. 整数转罗马数字(多语言实现)
罗马数字包含以下七种字符: I, V, X, L,C,D 和 M。 字符 数值 I 1 V 5 X 10 L 50 C 100 D 500 M 1000 例如, 罗马数字 2 写做 II ,即为两个并列的 1。12 写做 XII ,即为 X + II 。 27 写做 XXVII, 即为 XX + V + II 。 通常情况下,罗马数字中小的数字在大的数字的右边。但也存在特例,例如 4 不写做 IIII,而
|
8月前
|
自然语言处理 Rust 算法
【算法】10. 正则表达式匹配(多语言实现)
给你一个字符串 s 和一个字符规律 p,请你来实现一个支持 . 和 * 的正则表达式匹配。 . 匹配任意单个字符 * 匹配零个或多个前面的那一个元素 所谓匹配,是要涵盖 整个 字符串 s的,而不是部分字符串。
|
10月前
|
自然语言处理 Rust 算法
【算法】8. 字符串转换整数 (atoi)(多语言实现)
请你来实现一个 myAtoi(string s) 函数,使其能将字符串转换成一个 32 位有符号整数(类似 C/C++ 中的 atoi 函数)。 函数 myAtoi(string s) 的算法如下: 读入字符串并丢弃无用的前导空格 检查下一个字符(假设还未到字符末尾)为正还是负号,读取该字符(如果有)。 确定最终结果是负数还是正数。 如果两者都不存在,则假定结果为正。 读入下一个字符,直到到达下一个非数字字符或到达输入的结尾。字符串的其余部分将被忽略。 将前面步骤读入的这些数字转换为整数(即,"123" -> 123, "0032" -> 32)。如果没有读
|
存储 Rust 自然语言处理
【算法】7. 整数反转(多语言实现)
给你一个 32 位的有符号整数 x ,返回将 x 中的数字部分反转后的结果。 如果反转后整数超过 32 位的有符号整数的范围 [−231, 231 − 1] ,就返回 0。 假设环境不允许存储 64 位整数(有符号或无符号)。