vector 容器相关的练习

目录

一、只出现一次的数字

二、只出现一次的数字 II

三、只出现一次的数字 III

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

五、杨辉三角

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

七、电话号码的字母组合



一、只出现一次的数字

class Solution {
public:
    int singleNumber(vector& 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& 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 singleNumber(vector& nums) {
        vector 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& 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> generate(int numRows) {
        vector> 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

    vector> vv(numRows);

    vector 容器相关的练习_第1张图片

    假设 numRows 等于 5。

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

    vector 容器相关的练习_第2张图片

     


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

class Solution {
public:
    int MoreThanHalfNum_Solution(vector& 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& 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 letterCombinations(string digits) {
        vector v;
        if (digits.empty())
            return v;
​
        combine(digits, 0, "", v);
        return v;
    }
};

解析(示例一)

level number s
0 2 "abc"
1 3 "def"

你可能感兴趣的:(C++,算法,leetcode,数据结构)