在学习vector之后,来看一些比较经典的题目吧
最经典的还是用一个范围for 然后异或
class Solution {
public:
int singleNumber(vector<int>& nums) {
int val=0;
for(auto e:nums)
{
val^=e;
}
return val;
}
};
2.杨辉三角、
其实上一个博客里面我们就见过了vector<vector<int>> 的情况,C++写杨辉三角真的比C好太多
我们可以先开空间+初始化成1
然后 不在首尾的元素= 上一行前一列元素 +上一行这一列元素
class Solution {
public:
vector<vector<int>> generate(int numRows) {
vector<vector<int>> vv(numRows);
for(int i=0;i<numRows;i++)
{
vv[i].resize(i+1,1);
}
for(int i=2;i<vv.size();i++)
{
for(int j=1;j<i;j++)
{
vv[i][j]=vv[i-1][j-1]+vv[i-1][j];
}
}
return vv;
}
};
这里面首先要保存一个string储存每个按键的字符串,这里面的数字10必须写上
string _numstr[10]={"","","abc","def","ghi","jkl","mno","pqrs","tuv","wxyz"};
然后就是vector<string>的容器,判断一下,如果他传过来的数字串是空,那么直接返回“”
if(digits.empty())
{
return combin;
}
然后就是写一个递归的函数,这个和二叉树的遍历很像,只不过这里是多叉树的遍历
整体代码
class Solution {
string _numstr[10]={"","","abc","def","ghi","jkl","mno","pqrs","tuv","wxyz"};
public:
void Combin(const string& digits,int i,string combinstr,vector<string>& combin)
{
if(digits.size()==i)
{
combin.push_back(combinstr);
return ;
}
int num=digits[i]-'0';
string str=_numstr[num];
for(auto e:str)
{
Combin(digits,i+1,combinstr+e,combin);
}
}
vector<string> letterCombinations(string digits) {
vector <string> combin;
if(digits.empty())
{
return combin;
}
int i=0;
string str;
Combin(digits,i,str,combin);
return combin;
}
};
其实这个讲过很多遍了....很经典的想法,有点类似双指针
class Solution {
public:
int removeDuplicates(vector<int>& nums) {
if(nums.size()<2)
return nums.size();
int j=0;
for(int i=1;i<nums.size();i++)
{
if(nums[j]!=nums[i])
nums[++j]=nums[i];
}
return j+1;
}
};
class Solution {
public:
int singleNumber(vector<int>& nums) {
if(nums.size()==1)
return nums[0];
sort(nums.begin(),nums.end());
//std::sort(nums,nums+nums.size());
for(int i=0;i<nums.size()-2;i+=3)
{
if(nums[i]!=nums[i+2])
return nums[i];
}
return nums[nums.size()-1];
}
};
用到了分组异或的思想,看了一个大佬的解释很清楚
class Solution {
public:
vector<int> singleNumber(vector<int>& nums) {
/*分组异或(思路同645. 错误的集合)
现在假设两个只出现一次的数字是x,y,那么对全部数组数据进行异或后的结果就是x^y
1.分组异或的目的:要从x^y中分离出x和y,让x在一个组nums1中,y在另一个组nums2中
2.如何分组:
1)x,y一定是两个不同的数字,那么他们的二进制表达下就至少有一个位置数字不相同,而考虑一个事情:同一位置上01不同异或结果为1
2)分组依据:x^y中任意一个为1的位置,这个代表了x,y在这个位置上数字不同,这里为了方便我们就取低至高的第一个为1的位置
3.nums1全部异或结果 = x,nums2全部异或结果 = y
原因:两个相同的数字一定在同一组中,异或结果为0,自然两个分组全部异或的结果就是一个为x,一个为y
*/
//sumXOR:全部数组数据的异或和,也就是x^y
int sumXOR = 0;
for(int& n : nums){
sumXOR ^= n;
}
//寻找x^y中低至高的第一个为1的位置
int index = 1;
while(((sumXOR & index) == 0)){
index <<= 1;
}
//根据index把nums数组分成两个部分,也就是满足index & nums[i] == 1的是一组,否则就是另一组
int sumXOR1 = 0,sumXOR0 = 0;
for(int& num : nums){
if(index & num){
sumXOR1 ^= num;
}
else{
sumXOR0 ^= num;
}
}
return {sumXOR0,sumXOR1};
}
};
class Solution {
public:
int MoreThanHalfNum_Solution(vector<int> numbers) {
int a[10001]={0};
for(int i=0;i<numbers.size();i++)
{
a[numbers[i]]++;
if(a[numbers[i]]>(numbers.size()/2))
return numbers[i];
}
return 0;
}
};