LintCode 三数之和

1. 三数之和

给出一个有n个整数的数组S,在S中找到三个整数a, b, c,找到所有使得a + b + c = 0的三元组。
样例
如S = {-1 0 1 2 -1 -4}, 你需要返回的三元组集合的是:
(-1, 0, 1)
(-1, -1, 2)
注意
在三元组(a, b, c),要求a <= b <= c。结果不能包含重复的三元组。

solution:
因为三元组的元素是按照递增的顺序,因此我们首先需要对S进行排序。然后保持两个前后索引来进行比较。
code

class Solution {
public:    
    /**
     * @param numbers : Give an array numbers of n integer
     * @return : Find all unique triplets in the array which gives the sum of zero.
     */
    vector<vector<int> > threeSum(vector<int> &nums) {
        // write your code here   
        vector<vector<int>> res;
        sort(nums.begin(), nums.end()); //对数组进行排序
        int i = 0 , last = nums.size()-1;
        while (i < last) {
            int a = nums[i], j = i + 1, k = last;
            while (j < k) {
                int b = nums[j], c = nums[k];
                int sum = a + b + c;
                if (sum == 0)  res.push_back({a,b,c});
                if (sum <= 0)  //注意不能含有相同的索引
                    while (nums[j] == b && j < k ) ++j;
                if (sum >= 0)
                    while (nums[k] == c && j < k) --k;
            }
            while (nums[i] == a && i < last) ++i;
        }
        return res;        
    }
};

2. 三数之和 II

给一个包含n个整数的数组S, 找到和与给定整数target最接近的三元组,返回这三个数的和。
样例
例如S = [-1, 2, 1, -4] and target = 1. 和最接近1的三元组是 -1 + 2 + 1 = 2.
注意
只需要返回三元组之和,无需返回三元组本身

solution: 只需要把前面的问题与0进行比较改成target就可以了。
code:

class Solution {
public:    
    /**
     * @param numbers: Give an array numbers of n integer
     * @param target: An integer
     * @return: return the sum of the three integers, the sum closest target.
     */
    int threeSumClosest(vector<int> nums, int target) {
        // write your code here
        if (nums.size() < 3)
            return accumulate(nums.begin(), nums.end(), 0);
        sort(nums.begin(), nums.end());
        int ans = nums[0] + nums[1] + nums[2];
        int i = 0, last = nums.size()-1;
        int diff = 0;
        while (i < last) {
            int a = nums[i], j = i + 1, k = last;
            while (j < k) {
                int b = nums[j], c = nums[k];
                int sum = a + b + c;
                if (abs(sum - target) < abs(ans - target)) 
                    ans = sum;
                if (ans == target)
                    return ans;
                if (sum < target)
                    while (nums[j] == b && j < k) ++j;
                if (sum > target)
                    while (nums[k] == c && j < k) --k;
            }
            while (nums[i] == a && i < last) ++i;
        }
        return ans;
    }
};

3. 四数之和

给一个包含n个数的整数数组S,在S中找到所有使得和为给定整数target的四元组(a, b, c, d)。
样例
例如,对于给定的整数数组S=[1, 0, -1, 0, -2, 2] 和 target=0. 满足要求的四元组集合为:
(-1, 0, 0, 1)
(-2, -1, 1, 2)
(-2, 0, 0, 2)
注意
四元组(a, b, c, d)中,需要满足a <= b <= c <= d
答案中不可以包含重复的四元组。

solution:思路和前面的三数之和是一样的,算法复杂度O(n^3).

class Solution {
public:
    /**
     * @param numbers: Give an array numbersbers of n integer
     * @param target: you need to find four elements that's sum of target
     * @return: Find all unique quadruplets in the array which gives the sum of 
     *          zero.
     */
    vector<vector<int> > fourSum(vector<int> nums, int target) {
        // write your code here
        sort(nums.begin(), nums.end());
        vector<vector<int>> res;
        int i = 0, last = nums.size()-1;
        while (i < last) {
            int a = nums[i], j = i + 1;
            while (j < last) {
                int b = nums[j], k = j + 1, l = last;
                while (k < l) {
                    int c = nums[k], d = nums[l];
                    int sum = a + b + c + d;
                    if (sum == target) res.push_back({a,b,c,d});
                    if (sum <= target) 
                        while (nums[k] == c && k < l) ++k;
                    if (sum >= target)
                        while (nums[l] == d && k < l) --l;
                }
                while (nums[j] == b && j < last) ++j;
            }
            while (nums[i] == a && i < last) ++i;
        }
        return res;
    }
};
### LintCode 143 排颜色 II 的 C++ 实现 #### 背景介绍 LintCode 第 143 题名为“排颜色 II”,题目要求对数组中的三种颜色(0、1 和 2)进行原地排序,使得相同颜色的元素相邻,并按照红白蓝顺序排列。此题不允许使用库函数的排序功能[^2]。 以下是基于三指针法的高效解决方案: #### 解决方案分析 该算法的核心思想是通过三个指针分别追踪红色(0)、白色(1)和蓝色(2)的位置。遍历整个数组一次即可完成排序操作,时间复杂度为 O(n),空间复杂度为 O(1)[^2]。 #### C++ 实现代码 ```cpp #include <vector> using namespace std; class Solution { public: void sortColors2(vector<int>& nums) { int n = nums.size(); if (n == 0) return; int redIndex = 0; // 指向下一个应该放置红色的位置 int blueIndex = n - 1; // 指向下一个应该放置蓝色的位置 for (int i = 0; i <= blueIndex;) { // 使用循环控制索引移动 if (nums[i] == 0) { swap(nums[i], nums[redIndex]); ++redIndex; ++i; // 移动到下一位置 } else if (nums[i] == 2) { swap(nums[i], nums[blueIndex]); --blueIndex; // 不增加 i,因为交换后的值可能仍需处理 } else { ++i; // 当前值为 1,则跳过 } } } }; ``` 上述代码实现了高效的原地排序方法。`swap()` 函数用于交换两个元素的位置,从而调整它们在数组中的次序。 --- #### 关键点解析 1. **指针初始化**: `redIndex` 初始化为 0,表示第一个未被填充的颜色区域;`blueIndex` 初始化为最后一个元素下标,表示最后未被填充的颜色区域。 2. **边界条件**: 如果输入数组为空 (`n == 0`) 或仅有一个元素,则无需任何操作直接返回。 3. **优化细节**: 对于每次遇到颜色 2 的情况,由于其可能会覆盖尚未检查过的数据,因此需要保持当前索引不变以便重新评估新赋值的内容。 --- #### 时间与空间复杂度 - **时间复杂度**: 整体只需扫描一遍数组,故时间为线性级别 \(O(n)\)。 - **空间复杂度**: 所有操作均发生在原始数组上而无额外存储需求,因而空间消耗恒定为 \(O(1)\)。 ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值