zoukankan      html  css  js  c++  java
  • single number i && ii && iii

    Problem statement

     Elementary knowledge:

     There is a popular question when I seeked my job at Beijing: swap the value of two numbers without allocate a new memory.

     Normally, there are two solutions:

     1 int main(){
     2     int a = 3;
     3     int b = 5;
     4     
     5     a += b;
     6     b = a - b;
     7     a = a - b;
     8 
     9     a ^= b;
    10     b ^= a;
    11     a ^= b;
    12 
    13     return 0;
    14 }

    Some tricky:

    x&(x-1): eliminate the last 1 bit in x

    We can use this tricky to test if an integer is the power of 2 in O(1) time;

    class Solution {
    public:
        /*
         * @param n: An integer
         * @return: True or false
         */
        bool checkPowerOf2(int n) {
            // write your code here
            return n > 0 && (n & (n - 1)) == 0;
        }
    };

    Single Number

    Given an array of integers, every element appears twice except for one. Find that single one.

    Note: Your algorithm should have a linear runtime complexity. Could you implement it without using extra memory?

    Solution one:

    For this problem, we should use the knowledge that the XOR operation for two same number will be zero. 

     1 class Solution {
     2 public:
     3     int singleNumber(vector<int>& nums) {
     4         int single_val = 0;
     5         for(vector<int>::size_type ix = 0; ix < nums.size(); ix++){
     6             single_val ^= nums[ix];
     7         }
     8         return single_val;
     9     }
    10 };

    Solution two:

    Since the array is random, the first action is to sort the array from small to large.

    I keep a counter to count the number of current value. The loop ends at the element before the last one since we will compare current element with it`s direct next one. Because of this, we need do some boundary check to make sure there is at least one element in this array

    1. if they are equal, the counter + 1;
    2. if they are not equal:
      • if the counter is 2, that means current is already end in the array, we need precede to it`s next one, the counter should start from 1 again.
      • if the counter is less than 2( it should be 1), that means current only show up once, it is the single we want. return;
    3. If the function does not return in the while loop, that means the last element is the single value, we return nums.back();
     1 class Solution {
     2 public:
     3     int singleNumber(vector<int>& nums) {
     4         if(nums.empty()){
     5             return 0;
     6         }
     7         
     8         if(nums.size() == 1){
     9             return nums[0];
    10         }
    11         
    12         sort(nums.begin(), nums.end());
    13         int cnt = 1;
    14         for(vector<int>::size_type ix = 0; ix < nums.size() - 1; ix++){
    15             if(nums[ix] == nums[ix + 1]){
    16                 cnt++;
    17             } else {
    18                 if(cnt < 2){
    19                     return nums[ix];
    20                 } else {
    21                     cnt = 1;
    22                 }
    23             }
    24         }
    25         return nums.back();
    26     }
    27 };

    Single Number ii

    Given an array of integers, every element appears three times except for one, which appears exactly once. Find that single one.

    Note: Your algorithm should have a linear runtime complexity. Could you implement it without using extra memory?

    Solution one: 

    Frist solutiuon is the same with singlue number i, we just need change the value of cnt to be 3, it will works.

     1 class Solution {
     2 public:
     3     int singleNumber(vector<int>& nums) {
     4         if (nums.size() == 1) {
     5             return nums[0];
     6         }
     7         sort(nums.begin(), nums.end());
     8         int cnt = 1;
     9         for (vector<int>::size_type ix = 0; ix < nums.size(); ix++) {
    10             if (nums[ix] == nums[ix + 1]) {
    11                 cnt++;
    12             } else {
    13                 if (cnt < 3) {
    14                     return nums[ix];
    15                 } else {
    16                     cnt = 1;
    17                 }
    18             }
    19         }
    20         return nums.back();
    21     }
    22 };

    Solution two: 

    1. For each integer, it is represented by 32 bits, we count the number of "1"s for each i
    2. Do "module 3" operation and "or" operation to put it back to the result.
    3. Except the single value, other values occur three time, that means the bit should be zero if the count is moduled with 3.
    4. We will get the value of single number.
     1 class Solution {
     2 public:
     3     int singleNumber(vector<int>& nums) {
     4         int single_val = 0;
     5         int bit_sum = 0;
     6         for(int i = 0; i < 32; i++){
     7             bit_sum = 0;
     8             for(vector<int>::size_type ix = 0; ix < nums.size(); ix++){
     9                 bit_sum += (nums[ix] >> i) & 1;
    10             }    
    11             single_val |= (bit_sum % 3) << i;
    12         }
    13         return single_val;
    14     }
    15 };

    Solution three: 

    • ones: means the value when ith bit only occurs once
    • twos: means the value when ith bit only occurs twice
    • three: measn the value when ith bit only occurs third
     1 class Solution {
     2 public:
     3     int singleNumber(vector<int>& nums) {
     4         int one = 0, two = 0, three = 0;
     5         for (int i = 0; i < nums.size(); ++i) {
     6             two |= one & nums[i];
     7             one ^= nums[i];
     8             three = one & two;
     9             one &= ~three;
    10             two &= ~three;
    11         }
    12         return one;
    13     }
    14 };

    Single number iii

    Given an array of numbers nums, in which exactly two elements appear only once and all the other elements appear exactly twice. Find the two elements that appear only once.

    For example: Given nums = [1, 2, 1, 3, 2, 5], return [3, 5].

    Note:

    1. The order of the result is not important. So in the above example, [5, 3] is also correct.
    2. Your algorithm should run in linear runtime complexity. Could you implement it using only constant space complexity?

    The rules for xor operation:

    0: two bits are same

    1: two bits are different

    The xor operation is similiar with an addition without carry.

    Solution:

    There are two numbers only occur once, which is different with single number i. We can solve it with the single number i, however, we need do some precess before it.

    1. First, we do xor operations for all element in the array, the result is the xor of two number we want.
    2. Second, we should find one bit which is different in these two numbers and use this bit as an indicator to different them in next loop
    • The bit representation of a negative number is: reverse all bits of its positive number and plus one
    1. Third, loop all elements in array to do xor operation and get the answer.
     1 class Solution {
     2 public:
     3     vector<int> singleNumber(vector<int>& nums) {
     4         int xor_of_two_numbers = 0;
     5         for(vector<int>::size_type ix = 0; ix < nums.size(); ix++){
     6             // this is the result of the xor of two single numbers
     7             xor_of_two_numbers ^= nums[ix];
     8         }
     9         
    10         // the negative bit representation of each number
    11         // reverse all bits and plus one
    12         // find one bit from the xor result which this two single numbers is different
    13         // different them in next loop 
    14         int right_most_bit_of_xor = xor_of_two_numbers & -xor_of_two_numbers;
    15         
    16         vector<int> singleNumber(2);
    17         for(vector<int>::size_type ix = 0; ix < nums.size(); ix++){
    18             if(nums[ix] & right_most_bit_of_xor){
    19                 singleNumber[0] ^= nums[ix];
    20             } else {
    21                 singleNumber[1] ^= nums[ix];
    22             }
    23         }
    24         return singleNumber;
    25     }
    26 };
  • 相关阅读:
    上门量体不能停,量品打造“一人一版”的私人定制衬衫,半年覆盖30个城市
    直击中小互联网企业痛点,程序员客栈推出短期雇佣功能
    现在,培训老师也有可能是你未来的 Boss
    【蓝领日志】捷库,给B端提供蓝领员工的标准化培训工具
    【调研】华图教育:领跑公职培训市场
    社区服务中心+护理员培训+云平台,中康行健“一体两翼”构建养老生态体系
    餐厅孵化器“优粮生活”,用孵化模式打造统一独立外卖品牌
    语培市场热度不减,“手韩”背后的垂直领域空间在哪?
    母基金_百度百科
    小编亲测杭州最火的海南鸡饭,最好吃的居然是……-搜狐吃喝!!!
  • 原文地址:https://www.cnblogs.com/wdw828/p/6399817.html
Copyright © 2011-2022 走看看