0
点赞
收藏
分享

微信扫一扫

C++ 找出落单数题目汇总

JakietYu 2022-04-02 阅读 64
c++力扣

目录

一个数组除了一个元素只出现一次以外,其他元素都出现两次,写程序找出只出现一次的数字。(力扣 136 只出现一次的数字)

除某个元素仅出现 一次 外,其余每个元素都恰出现 三次 。请你找出并返回那个只出现了一次的元素。(力扣 137 只出现一次数字 II)

其中恰好有两个元素只出现一次,其余所有元素均出现两次。 找出只出现一次的那两个元素。你可以按 任意顺序 返回答案。(力扣 260 只出现一次数字 III) 


  • 一个数组除了一个元素只出现一次以外,其他元素都出现两次,写程序找出只出现一次的数字。(力扣 136 只出现一次的数字)

解法一:异或运算

思路:两个相同数异或结果为0,0与任何数异或得它本身。

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

 解法二:哈希表

class Solution {
public:
    int singleNumber(vector<int>& nums) {
        unordered_map<int,int> map;
        for(int num:nums)
            map[num]++;
        for(int num:nums)
            if(map[num] == 1) return num;
        return 0;
    }
};

map 和unordered_map

map:元素有序,查询性能稳定

unordered_map:元素无序,查询速度快,平均性能接近O(1) 

  • 除某个元素仅出现 一次 外,其余每个元素都恰出现 三次 。请你找出并返回那个只出现了一次的元素。(力扣 137 只出现一次数字 II)

解法一:位运算

class Solution {
public:
    int singleNumber(vector<int>& nums) {
         int res = 0;
         for(int i = 0; i < 32; i++){
         int count = 0;
         for (int j = 0; j < nums.size(); j++) {
              if ((nums[j] >> i & 1) == 1) {
                  count++;
              }             
          }
          if (count % 3 != 0) {
              res = res | 1 << i;
          }
      }
      return res;       
    }

};

方法二:哈希表

class Solution {
public:
    int singleNumber(vector<int>& nums) {
        unordered_map<int, int> map;
        for (int num: nums) {
            ++map[num];
        }
        int ans = 0;
        for (auto [num, occ]: map) {
            if (occ == 1) {
                ans = num;
                break;
            }
        }
        return ans;
    }
};

for(auto a :b)//b是一个容器,利用a遍历并获得b容器的每一个值,但a不能影响b中的元素。

for(auto &a : b)//可以通过对a赋值来对b中内容填充。 

  • 其中恰好有两个元素只出现一次,其余所有元素均出现两次。 找出只出现一次的那两个元素。你可以按 任意顺序 返回答案。(力扣 260 只出现一次数字 III) 

解法一:位运算

思路:把所有的元素进行异或操作,最终得到一个异或值。因为是不同的两个数字,所以这个值必定不为 0;得最低位不相等的一位;为 0 的分为一个数组,为 1 的分为另一个数组。这样就把问题降低成了:“有一个数组每个数字都出现两次,有一个数字只出现了一次,求出该数字”。

class Solution {
public:
    vector<int> singleNumber(vector<int>& nums) {
        int xorsum = 0;
        for (int num: nums) {
            xorsum ^= num;
        }
        int lsb =  xorsum & (-xorsum);
        int type1 = 0, type2 = 0;
        for (int num: nums) {
            if (num & lsb) {
                type1 ^= num;
            }
            else {
                type2 ^= num;
            }
        }
        return {type1, type2};
    }
};

a & (-a) 可以获得a最低的非0位 

解法二:哈希表

class Solution {
public:
    vector<int> singleNumber(vector<int>& nums) {
        unordered_map<int, int> map;
        for (int num: nums) {
            ++map[num];
        }
        vector<int> ans;
        for (const auto& [num, occ]: map) {
            if (occ == 1) {
                ans.push_back(num);
            }
        }
        return ans;
    }
};
举报

相关推荐

0 条评论