剑指Offer | 整数运算02(中等)

剑指 Offer II 004. 只出现一次的数字


题目描述:

给你一个整数数组 nums ,除某个元素仅出现 一次 外,其余每个元素都恰出现 三次 。请你找出并返回那个只出现了一次的元素。


示例:

输入:nums = [2,2,3,2]
输出:3

限制:

1.1 <= nums.length <= 3 * 104
2.-231 <= nums[i] <= 231 - 1
3.nums 中,除某个元素仅出现 一次 外,其余每个元素都恰出现 三次

思路:

class Solution {
public:
    int singleNumber(vector<int>& nums) {
        vector<int> bitSum(32, 0);
        for (const int num : nums) {
            for (int i = 0; i < 32; ++i) {
                bitSum[i] += (num >> (31 - i)) & 1;
            }
        }
        int ret = 0;
        for (int i = 0; i < 32; ++i) {
            ret = (ret << 1) + bitSum[i] % 3;
        }
        return ret;
    }
};



剑指 Offer II 005. 单词长度的最大乘积


题目描述:

给定一个字符串数组 words,请计算当两个字符串 words[i]words[j] 不包含相同字符时,它们长度的乘积的最大值。假设字符串中只包含英语的小写字母。如果没有不包含相同字符的一对字符串,返回 0。


示例:

输入: words = ["abcw","baz","foo","bar","fxyz","abcdef"]
输出: 16 
解释: 这两个单词为 "abcw", "fxyz"。它们不包含相同字符,且长度的乘积最大。

限制:

1.2 <= words.length <= 1000
2.1 <= words[i].length <= 1000
3.words[i] 仅包含小写字母

思路:

class Solution {
public:
    int maxProduct(vector<string>& words) {
        int m = words.size();
        unordered_map<int, int> bitMaskMap;
        for (int i = 0; i < m; i++) {
            int bitMask = 0;
            for (char c : words[i]) {
                bitMask |= 1 << (c - 'a');
            }
            if (bitMaskMap.count(bitMask)) {
                int maxV = max(bitMaskMap[bitMask], (int)words[i].size());
                bitMaskMap[bitMask] = maxV;
            } else {
                bitMaskMap[bitMask] = words[i].size();
            }
        }

        int ans = 0;
        for (auto& x : bitMaskMap) {
            for (auto& y : bitMaskMap) {
                if ((x.first & y.first) == 0) {
                    ans = max(ans, x.second * y.second);
                }
            }
        }
        return ans;
    }
};



剑指 Offer II 006. 排序数组中两个数字之和


题目描述:

给定一个已按照 升序排列 的整数数组 numbers ,请你从数组中找出两个数满足相加之和等于目标数 target


示例:

输入:numbers = [1,2,4,6,10], target = 8
输出:[1,3]
解释:2 与 6 之和等于目标数 8 。因此 index1 = 1, index2 = 3 。

限制:

1.2 <= numbers.length <= 3 * 104
2.-1000 <= numbers[i] <= 1000
3.numbers 按 递增顺序 排列
4.-1000 <= target <= 1000
5.仅存在一个有效答案

思路:

class Solution {
public:
    vector<int> twoSum(vector<int>& numbers, int target) {
        int left = 0;
        int right = numbers.size() - 1;
        while (left < right) {
            int cur = numbers[left] + numbers[right];
            if (cur == target) {
                return {left, right};
            }
            else {
                cur > target ? right-- : left++;
            }
        }
        return {};
    }
};


posted @ 2021-09-25 23:28  不是勇士  阅读(38)  评论(0)    收藏  举报