【C++】速通涉及 “vector” 的经典OJ编程题

一. 杨辉三角

本题LeetCode链接:
在这里插入图片描述

解题思路:

利用vector的特性创建一个二维数组,通过观察得知杨辉三角的0行0列全为1,其他位置元素的值都等于其上一行同列元素与上一行前一列元素的和。

代码实现:

class Solution {
public:
    vector<vector<int>> generate(int numRows) {
        vector<vector<int>> arr(numRows);
         for(int i = 0; i < numRows; i++)
        {
            //arr[i].resize(i + 1, 1);//将开辟的空间全初始化为1
            arr[i].resize(i + 1);
            arr[i][0] = arr[i][i] = 1;
        }

        //第一、二行的元素都是1,从第3行,第2列开始循环
        for(int i = 2; i < numRows; i++)
        {
            for(int j = 1; j < i; j++)
            {
                arr[i][j] = arr[i - 1][j] + arr[i - 1][j - 1];
            }
        }
        return arr;
    }
};

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

本题LeetCode链接:
在这里插入图片描述

解题思路:

比较相邻的两个元素是否相等,若不相等则依次从原数组第二个位置(即变量index,下标为1)插入到原数组中

代码实现:

class Solution {
public:
    int removeDuplicates(vector<int>& nums) {
        int index = 1;
        for(int i = 0; i < nums.size() - 1; i++)//注意下面的i + 1越界情况
        {
            if(nums[i] != nums[i + 1])
            {
                nums[index] = nums[i + 1];
                index++;
            }
        }
        //由于一旦发生交换后index就会++;所以此时index的大小就为最终长度
        return index;
    }
};

【C/C++】按位运算符使用规制

1. 按位与(&):两个相应的二进制位都为1时,结果为1,否则为0。
2. 按位或(|):两个相应的二进制位只要有一个为1,结果为1。
3. 按位异或(^):两个相应的二进制位相异时,结果为1,相同时,结果为0。
4. 按位取反(~):对一个二进制数按位取反,即0变为1,1变为0。
5. 左移(<<):将一个二进制数的各位全部左移若干位,高位丢弃,低位补0。
6. 右移(>>):将一个二进制数的各位全部右移若干位,低位丢弃,高位补符号位

三. 只出现一次的数字

本题LeetCode链接:
在这里插入图片描述

解题思路:

0异或任何一个数的结果为该数本身,两个相同的整数异或结果为0;

代码实现:

class Solution {
public:
    int singleNumber(vector<int>& nums) {
        int num = 0;
        for(auto ch : nums)
        {
            num ^= ch;
        }
        return num;
    }
};

四. 只出现一次的数字 III

本题LeetCode链接:
在这里插入图片描述

解题思路:

由于给定的整数序列中恰好有两个元素只出现一次,其余所有元素均出现两次;
将全部元素异或到sum(值为0)中就是这两个元素的异或结果(1.两个相等的元素异或结果为0;2.任何一整数异或0的结果为它本身);由于这两个数不相等,那么异或的结果sum中至少有一个二进制比特位的值为1,我们这里就找到结果sum中的最低的且值为1的比特位,并且把sum中的其他比特位都改变为0得到 lowbit(通过sum ^ -sum得到lowbit,lowbit其他比特位数值均为0);这就是这两个不同的元素的区别,再利用按位与(&)的特征来找到这两个不同的元素;此时用lowbit的唯一的数值为1的比特位来作为判断条件,分别用两个0异或原数组中的所以元素,由于其他元素均出现且只出现了两次,不管异或到哪个0这两个相同整数异或结果都是0,不会影响到最终要找的这两个不同元素。

关键声明:

     s = 101100
    ~s = 010011
(~s)+1 = 010100 // 根据补码的定义,这就是 -s   效果:s 的最低 1 左侧取反,右侧不变
s & -s = 000100 // lowbit

作者:灵茶山艾府
链接:https://leetcode.cn/problems/single-number-iii/solutions/2484352/tu-jie-yi-zhang-tu-miao-dong-zhuan-huan-np9d2/
来源:力扣(LeetCode)

代码实现:

class Solution {
public:
    vector<int> singleNumber(vector<int>& nums) {
        size_t sum = 0;
        for(auto ch : nums)
        {
            sum ^= ch;
        }

        //只保留一个二进制数最低位的1,其他位均为0;
        size_t lowbit = sum & -sum;//此处要用size_t,解决溢出情况

        int type1 = 0,type2 = 0;//此处不可以用size_t,与vector<int>不匹配
        for(auto ch : nums)
        {
            if(lowbit & ch)
            {
                type1 ^= ch;
            }
            else
            {
                type2 ^= ch;
            }
        }

      return  {type1, type2};
      
        //vector<int> ans(2,0);
        //for(auto ch : nums)
        //{
            //ans[(ch & lowbit) == 0] ^= ch; 
        //}
        //return ans;
    }
};
评论 31
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值