15. 三数之和(C++题解版含VS可运行源码)

15. 三数之和(C++题解版含VS可运行源码)

1.力扣C++源码

class Solution {
    
    
public:
    vector<vector<int>> threeSum(vector<int>& nums) {
    
    
        int len = nums.size();
        if (len < 3)return {
    
    };//特判1,数组元素<3,返回空数组
        vector<vector<int>> ans;//定义一个vector类型的二维数组存储符合的结果数组
        sort(nums.begin(), nums.end());//默认升序
        for (int a = 0; a < len - 2; a++) {
    
    //固定外层循环
            if (nums[a] > 0)return ans;//特判2,当a>0时,就停止循环,返回结果
            if (a > 0 && nums[a] == nums[a - 1])continue;//去重,跳到循环开始处
            int b = a + 1;//定义左指针b
            int c = len - 1;//定义右指针c
            while (b < c) {
    
    //当b<c的时候,继续循环;b>=c的时候就停止指针移动
                if (nums[b] + nums[c] > -nums[a])c--;//数太大了,c指针左移
                else if (nums[b] + nums[c] < -nums[a])b++;//数太小了,b指针右移
                else {
    
    //正好=0
                    ans.push_back(vector<int>{
    
    nums[a], nums[b], nums[c]});
                    c--;
                    b++;
                    //双指针缩小空间时,也需要考虑去重
                    //例如:[-4,1,1,1,2,3,3,3], a=0, b=1, c=7
                    while (b < c && nums[c] == nums[c + 1])c--;//右去重
                    while (b < c && nums[b] == nums[b - 1])b++;//左去重
                }
            }
        }
        return ans;

    }
};

2.题解

//算法思路:排序 + 双指针
//1特判,对于数组长度 len,如果数组为 null 或者数组长度小于 3,返回[]。
//2对数组进行排序。
//3遍历排序后数组:
//(1)若 nums[i] > 0:因为已经排序好,所以后面不可能有三个数加和等于 0,直接返回结果。
//(2)对于重复元素:跳过,避免出现重复解
//(3)令左指针 b = a + 1,右指针 c = len - 1,当 b < c 时,执行循环:
//    1>当 nums[a] + nums[b] + nums[c] == 0 执行循环,判断左界和右界是否和下一位置重复,
//      去除重复解。并同时将 b, c 移到下一位置,寻找新的解
//    2>若和大于 0,说明 nums[c] 太大,c 左移,即 c–;
//    3>若和小于 0,说明 nums[b] 太小,b 右移,即 b++;

3.VS可运行源码

#include<stdio.h>
#include<stdlib.h>
#include<iostream>
#include<vector>
#include<algorithm>
#pragma warning(disable:4996)
using namespace std;

//算法思路:排序 + 双指针
//1特判,对于数组长度 len,如果数组为 null 或者数组长度小于 3,返回[]。
//2对数组进行排序。
//3遍历排序后数组:
//(1)若 nums[i] > 0:因为已经排序好,所以后面不可能有三个数加和等于 0,直接返回结果。
//(2)对于重复元素:跳过,避免出现重复解
//(3)令左指针 b = a + 1,右指针 c = len - 1,当 b < c 时,执行循环:
//    1>当 nums[a] + nums[b] + nums[c] == 0 执行循环,判断左界和右界是否和下一位置重复,
//      去除重复解。并同时将 b, c 移到下一位置,寻找新的解
//    2>若和大于 0,说明 nums[c] 太大,c 左移,即 c–;
//    3>若和小于 0,说明 nums[b] 太小,b 右移,即 b++;

class Solution {
    
    
public:
    vector<vector<int>> threeSum(vector<int>& nums) {
    
            
        int len = nums.size();
        if (len < 3)return {
    
    };//特判1,数组元素<3,返回空数组
        vector<vector<int>> ans;//定义一个vector类型的二维数组存储符合的结果数组
        sort(nums.begin(), nums.end());//默认升序
        for (int a = 0; a < len - 2; a++) {
    
    //固定外层循环
            if (nums[a] > 0)return ans;//特判2,当a>0时,就停止循环,返回结果
            if (a > 0 && nums[a] == nums[a - 1])continue;//去重,跳到循环开始处
            int b = a + 1;//定义左指针b
            int c = len - 1;//定义右指针c
            while (b < c) {
    
    //当b<c的时候,继续循环;b>=c的时候就停止指针移动
                if (nums[b] + nums[c] > -nums[a])c--;//数太大了,c指针左移
                else if (nums[b] + nums[c] < -nums[a])b++;//数太小了,b指针右移
                else {
    
    //正好=0
                    ans.push_back(vector<int>{
    
    nums[a], nums[b], nums[c]});
                    c--;
                    b++;
                    //双指针缩小空间时,也需要考虑去重
                    //例如:[-4,1,1,1,2,3,3,3], a=0, b=1, c=7
                    while (b < c && nums[c] == nums[c + 1])c--;//右去重 这里注意c+1
                    while (b < c && nums[b] == nums[b - 1])b++;//左去重 这里注意b-1
                }
            }
        }
        return ans;
    }
};
int main()
{
    
    
    printf("输入数组元素个数:");
    int n;
    scanf("%d", &n);

    printf("输入数组元素:");
    vector<int> nums;
    int num;
    for (int i = 0; i < n; i++) {
    
    
        scanf("%d", &num);
        nums.push_back(num);
    }
    //for (int i = 0; i < n; i++) {
    
    
    //    printf("%d ", nums[i]);//vector用下表访问元素
    //}

    Solution test;//定义类变量test,用test调用相应函数
    vector<vector<int>> ans = test.threeSum(nums);//ans相当于一个二维数组
    for (int i = 0; i < ans.size(); i++) {
    
    //ans.size():ans中的vector容器的个数(二位数组行数)
        for (int j = 0; j < ans[i].size(); j++) {
    
    //ans[i].size():ans中第i个vector容器的长度(每个vector中元素个数)
            printf("%d ", ans[i][j]);//vector用下表访问元素
        }
        printf("\n");
    }
    
	return 0;
}

Guess you like

Origin blog.csdn.net/weixin_45784564/article/details/121430664