vector 容器相关的练习

目录

一、只出现一次的数字

二、只出现一次的数字 II

三、只出现一次的数字 III

四、删除有序数组中的重复项

五、杨辉三角

六、数组中出现次数超过一半的数字

七、电话号码的字母组合



一、只出现一次的数字

class Solution {
public:
    int singleNumber(vector<int>& nums) {
        int ans = nums[0];
        for (size_t i = 1; i < nums.size(); ++i)
        {
            ans ^= nums[i];
        }
        return ans;
    }
};


二、只出现一次的数字 II

class Solution {
public:
    int singleNumber(vector<int>& nums) {
        int ans = 0;
        // 求只出现一次的数字的二进制表示的每一位
        for (size_t i = 0; i < 32; ++i)
        {
            size_t cnt = 0;
            // 遍历整个数组,统计第 i 位为 1 的数字的个数
            for (size_t j = 0; j < nums.size(); ++j)
            {
                if (nums[j] & (1 << i))
                    ++cnt;
            }
            
            if (cnt % 3 == 1)  // cnt 为 1,或者为 1 + 3 * k
                ans |= (1 << i);
        }
        return ans;
    }
};


三、只出现一次的数字 III

class Solution {
public:
    vector<int> singleNumber(vector<int>& nums) {
        vector<int> v(2);
​
        int res = nums[0];
        for (size_t i = 1; i < nums.size(); ++i)
        {
            res ^= nums[i];
        }
​
        // 找到 res 的二进制表示中最低位的 1 的位置
        size_t pos = 0;
        for (size_t i = 0; i < 32; ++i)
        {
            if (res & (1 << i))
            {
                pos = i;
                break;
            }
        }
​
        // 根据第 pos 位是否为 1 将 nums 分为两组
        for (size_t i = 0; i < nums.size(); ++i)
        {
            if (nums[i] & (1 << pos))
                v[0] ^= nums[i];
            else
                v[1] ^= nums[i];
        }
        return v;
    }
};


四、删除有序数组中的重复项

class Solution {
public:
    int removeDuplicates(vector<int>& nums) {
        size_t slow = 0;
        for (size_t fast = 1; fast < nums.size(); ++fast)
        {
            if (nums[slow] != nums[fast])
                nums[++slow] = nums[fast];
        }
        return slow + 1;
    }
};


五、杨辉三角

class Solution {
public:
    vector<vector<int>> generate(int numRows) {
        vector<vector<int>> vv(numRows);
​
        for (size_t i = 0; i < numRows; ++i)
        {
            vv[i].resize(i + 1, 0);
            vv[i][0] = vv[i][i] = 1;
​
            if (i >= 2)
            {
                for (size_t j = 1; j < i; ++j)
                {
                    vv[i][j] = vv[i - 1][j - 1] + vv[i - 1][j];
                }
            }
        }
​
        return vv;
    }
};

图解

  1. 定义一个包含 numRows 个元素的动态二维数组 vv,每个元素的类型都是 vector<int>

    vector<vector<int>> vv(numRows);

    假设 numRows 等于 5。

  2. 生成杨辉三角的前 numRows 行。

     


六、数组中出现次数超过一半的数字

class Solution {
public:
    int MoreThanHalfNum_Solution(vector<int>& numbers) {
        int candidate = numbers[0];
        int chance = 1;
        for (size_t i = 1; i < numbers.size(); ++i)
        {
            if (chance != 0)
            {
                if (candidate == numbers[i])
                    ++chance;
                else
                    --chance;
            }
            else
            {
                candidate = numbers[i];
                chance = 1;
            }
        }
        return candidate;
    }
};
  1. 思路

    如果两个数字不相等,就消去这两个数,由于数组中有一个数字出现的次数超过数组长度的一半,即众数,那么即便在最坏情况下,每次消去一个众数和非众数,最后留下来的数也一定是众数。

  2. 具体操作

    在遍历数组时保存两个值,分别是众数的候选者 candidate 以及其所剩的机会 chance。当我们遍历到下一个元素的时候,如果下一个元素和候选者相等,则机会加 1,如果不相等,则机会减 1,即消去这两个不相同的数字。如果遍历到下一个元素的时候,机会为 0,即意味着需要重新选候选人了。


七、电话号码的字母组合

class Solution {
public:
    string map[10] = { "", "", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz" };
​
    void combine(const string& digits, size_t level, string combination, vector<string>& v)
    {
        if (level == digits.size())
        {
            v.push_back(combination);
            return;
        }
​
        int number = digits[level] - '0';
        string s = map[number];
        for (size_t i = 0; i < s.size(); ++i)
        {
            combine(digits, level + 1, combination + s[i], v);
        }
    }
​
    vector<string> letterCombinations(string digits) {
        vector<string> v;
        if (digits.empty())
            return v;
​
        combine(digits, 0, "", v);
        return v;
    }
};

解析(示例一)

levelnumbers
02"abc"
13"def"

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值