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
Share
分布式系统的经典基础
这篇文章主要讲了分布式系统的设计思想、CAP理论以及BASE理论。