ARTS 第三周

Algorithm

15.三数之和

给定一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?找出所有满足条件且不重复的三元组。

注意:答案中不可以包含重复的三元组。

例如, 给定数组 nums = [-1, 0, 1, 2, -1, -4],

满足要求的三元组集合为:
[
[-1, 0, 1],
[-1, -1, 2]
]
思路1:两层for循环遍历前两个数(这里可以确保第一个小于等于第二个数),判断第三个数是否在集合中(如果小于第二个数,直接改变第一个数进行下次循环)。坑点写在代码里。这个时间复杂度是O((n^2)*logn),效率有点低。

class Solution {
public:
    vector<vector<int> > threeSum(vector<int>& nums) {
		vector<vector<int> > res;
        if(nums.size() < 3) return res;//特判一下元素小于3的时候,结果肯定是为空的。
        sort(nums.begin(), nums.end());
        if(nums[0] == 0 && nums[nums.size()-1] == 0){//特判一下当第一个数和最后一个都是零,那么中间也肯定是0,那么结果只有一种。 0 0 0
        	vector<int> vec;
        	vec.push_back(0);
			vec.push_back(0);
			vec.push_back(0);
			res.push_back(vec);
			return res;
		}
        if(nums[0] > 0 || nums[nums.size()-1] < 0) return res;//特判如果没有正数或没有负数的时候,结果肯定为空。
		for(int i=0;i<nums.size()-2;i++){//要注意这里的nums.size()返回的是unsigned的,如果nums.size()-2 < 0,那么就溢出了。
        	for(int j=i+1;j<nums.size()-1;j++){
        		int third=0-nums[i]-nums[j];
        		//cout<<nums[i]<<" "<<nums[j]<<" "<<third<<endl;
        		if(third < nums[j]){
					break;
				}
				vector<int>::iterator it=lower_bound(nums.begin()+j+1, nums.end(), third);
				if(it == nums.end()) continue;
				if((*it) == third){
					//cout<<"yes"<<endl;
					vector<int> vec;
					vec.push_back(nums[i]);
					vec.push_back(nums[j]);
					vec.push_back(third);
					if(s.find(vec) == s.end()){
						s.insert(vec);
						res.push_back(vec);
					}
				}
			}
		}
        return res;
    }
private: 
	set<vector<int> > s;
};

思路二:遍历第一个元素,然后用两个指针分别指向剩下元素的首尾(第二个元素和第三个),遍历是否可以找到第二三个元素的和等于 0-第一个元素。这种算法的时间复杂度是O(n^2),这个算法实在评论区找到的。

class Solution {
    public List<List<Integer>> threeSum(int[] nums) {
        Arrays.sort(nums);
        List<List<Integer>> ls = new ArrayList<>();
        for (int i = 0; i < nums.length - 2; i++) {
            if (i == 0 || (i > 0 && nums[i] != nums[i - 1])) {//如果前一个等于当前这个,已经遍历过了,就不需要再遍历了。
                int l = i + 1, r = nums.length - 1, sum = 0 - nums[i];
                while (l < r) {//用两个指针分别指向首尾
                    if (nums[l] + nums[r] == sum) {
                        ls.add(Arrays.asList(nums[i], nums[l], nums[r]));
                        while (l < r && nums[l] == nums[l + 1]) l++;//跳过已经计算过的值
                        while (l < r && nums[r] == nums[r - 1]) r--;
                        l++;
                        r--;
                    } else if (nums[l] + nums[r] < sum) {
                        while (l < r && nums[l] == nums[l + 1]) l++;
                        l++;
                    } else {
                        while (l < r && nums[r] == nums[r - 1]) r--;
                        r--;
                    }
                }
            }
        }
        return ls;
    }
}

Review

原文地址: How to teach endian
字节序的总结

Tip

Cookie和Session简述

Share

分布式系统的经典基础
这篇文章主要讲了分布式系统的设计思想、CAP理论以及BASE理论。

猜你喜欢

转载自blog.csdn.net/qq_39513105/article/details/89068643