只出现一次的数字
点击访问
思路一:哈希集合表
① 建立哈希集合表unordered_set<int, int> hash
② 遍历数组中的元素,每次遍历判断元素在集合中的个数是否存在,若已经存在就删除,否则就进入集合。最终这个操作使得集合只剩下一个元素,这个元素就是只出现一次的数字。
class Solution {
public:
int singleNumber(vector<int>& nums) {
auto it = nums.begin();
unordered_set<int> myHash;
while(it != nums.end()){
if(myHash.count(*it)) //说明集合已经存在这个数了
myHash.erase(*it); //删除
else
myHash.insert(*it); //加入
it++;
}
return *myHash.begin();
}
};
思路二:位运算——XOR
XOR是异或运算,通过下面的例子就可以知道这个方法的妙处:
11001⊗11001 = 00000
11001⊗11000 = 00001
(异或意思是二元组元素相互不一致,且必须是1或0的组合,比如1⊗1=0而1⊗0=1)
这样可以知道在一系列只有一个数字与其他数字不一致时,有下列的等式:
(a_1⊗a_2)…(a_n-2⊗a_n-1)⊗a_n = 0⊗0⊗…⊗0⊗a_n = 0⊗a_n = a_n
因此连续的异或运算之后,最终结果就是只出现一次的数字!
//异或运算
class Solution {
public:
int singleNumber(vector<int>& nums) {
int ret = 0;
for(auto i : nums) ret ^= i;
return ret;
}
};
多数元素
添加链接描述
思路一:哈希表
建立哈希表,遍历数组,每次遍历元素都进入哈希表,当哈希值 > [n/2]的时候返回元素即可,否则返回-1
class Solution {
public:
int majorityElement(vector<int>& nums) {
int n = nums.size() / 2;
unordered_map<int, int> hash;
for(auto i : nums){
if(++hash[i] > n) return i;
}
return -1;
}
};
思路二:排序法
有数学知识可以知,排序后的数组,在array[n/2]位置时对应的数字,它的出现次数总是大于[n / 2]的。原因在于,排序后所有重复的数字都相邻靠近在一起,而中间的数字([n / 2])一定是大于n / 2次数的数字:
class Solution {
public:
int majorityElement(vector<int>& nums) {
sort(nums.begin(), nums.end());
return nums[nums.size() / 2];
}
};
三数之和
添加链接描述
思路:双指针+排序
先排序,使得序列有序
i变量初始值为0
然后指针L处于 i + 1,R处于size - 2;
从头开始遍历
如果nums[0]>0,则不存在
否则遍历,每次遍历都要检查是否重合,条件即为:nums[i] == nums[i-1]
后定义sum = nums[i]+nums[L]+nums[R]
若sum>0,说明和大于0,需要减小,所以向左移动R指针,每次移动都要判断是否重合:
while(i<j && nums[–R] == nums[R]);
若sum<0,说明和小于0,需要增大,所以向右移动L指针,每次移动都要判断是否重合:
while(i<j && nums[++i] == nums[i]);
class Solution {
public static List<List<Integer>> threeSum(int[] nums) {
List<List<Integer>> ans = new ArrayList();
int len = nums.length;
if(nums == null || len < 3) return ans;
Arrays.sort(nums); // 排序
for (int i = 0; i < len ; i++) {
if(nums[i] > 0) break; // 如果当前数字大于0,则三数之和一定大于0,所以结束循环
if(i > 0 && nums[i] == nums[i-1]) continue; // 去重
int L = i+1;
int R = len-1;
while(L < R){
int sum = nums[i] + nums[L] + nums[R];
if(sum == 0){
ans.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 (sum < 0) L++;
else if (sum > 0) R--;
}
}
return ans;
}
}
/*
from作者:guanpengchn
链接:https://leetcode-cn.com/problems/3sum/solution/hua-jie-suan-fa-15-san-shu-zhi-he-by-guanpengchn/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。*/