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

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

  • 一. 杨辉三角
    • 解题思路:
    • 代码实现:
  • 二. 删除有序数组中的重复项
    • 解题思路:
    • 代码实现:
      • 【C/C++】按位运算符使用规制
  • 三. 只出现一次的数字
    • 解题思路:
    • 代码实现:
  • 四. 只出现一次的数字 III
    • 解题思路:
    • 代码实现:

一. 杨辉三角

本题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得到);这就是这两个不同的元素的区别,再利用按位与(&)的特征来找到这两个不同的元素。

关键步骤声明:

     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;
    }
};
上一篇:二叉树的中序&后序遍历——非递归版本


下一篇:ICM20948 DMP代码详解(64)