【C++】vactor刷题(数组中出现次数超过一半的数字,只出现一次的数字一二三,杨辉三角 ,电话号码的字母组合)

在学习vector之后,来看一些比较经典的题目吧

1.只出现一次是的数字 

最经典的还是用一个范围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;
    }
};

3.电话号码的字母组合

这里面首先要保存一个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;
    }
};

4.删除有序数组中的重复项

其实这个讲过很多遍了....很经典的想法,有点类似双指针

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;
    }
};

5.只出现一次的数字②

 

 

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];
    }
};

 6.只出现一次的数据③

 用到了分组异或的思想,看了一个大佬的解释很清楚

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};
    }
};

7.数组中出现次数超过一半的数字

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;
    }
};

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值