LeetCode-136&137&260.Single Number

136 https://leetcode.com/problems/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?

public int SingleNumber(int[] nums) 
    {
        int res = nums[0];
        for (int i = 1; i < nums.Length; i++)
            res ^= nums[i];
        return res;
    }


137 https://leetcode.com/problems/single-number-ii/

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

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

解法1

int 数据共有32位,可以用32变量存储 这 N 个元素中各个二进制位上  1  出现的次数,最后 在进行 模三 操作,如果为1,那说明这一位是要找元素二进制表示中为 1 的那一位。时间:O(32*N),这是一个通用的解法,如果把出现3次改为 k 次,那么只需模k就行了。

public int SingleNumber(int[] nums)
    {
        int n = nums.Length, res = 0;
        int[] bitnum = new int[32];
        for (int i = 0; i < 32; i++)
        {
            for (int j = 0; j < n; j++)
            {
                bitnum[i] += (nums[j] >> i) & 1;
            }
            res |= (bitnum[i] % 3) << i;
        }
        return res;
    }

解法2

三个变量分别保存各个二进制位上 1 出现一次、两次、三次的分布情况

 public int SingleNumber(int[] nums)
    {
        int n = nums.Length;
        int one = 0, two = 0, three = 0;
        for (int i = 0; i < n; i++)
        {
            two |= one & nums[i];
            one ^= nums[i];
            three = one & two;
            one &= ~three;
            two &= ~three;
        }
        return one;
    }

参考 http://blog.csdn.net/jiadebin890724/article/details/23306837


扩展 http://www.cnblogs.com/daijinqiao/p/3352893.html


260 https://leetcode.com/problems/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?

public int[] SingleNumber(int[] nums)
        {
            int n = nums.Length;
            //res存放两个出现单次的数的异或结果,比如a和b
            int res = nums[0];
            for (int i = 1; i < n; i++)
                res ^= nums[i];

            //找到res中第1个1的位置,因为a!=b,所以肯定至少有一个是1,然后根据这个位是否为1将numns拆成两组,再分别异或
            int index = 0;
            while ((res&1)==0)
            {
                index++;
                res >>= 1;
            }

            int num1 = 0, num2 = 0;
            for (int i = 0; i < n; i++)
            {
                if (((nums[i] >> index) & 1) == 0)
                    num1 ^= nums[i];
                else
                    num2 ^= nums[i];
            }
            return new int[] { num1, num2 };
        }

参考  http://www.wengweitao.com/lintcode-single-number-i-ii-iii-luo-dan-de-shu.html

找第一个为1的数可以使用下面的表达式

C-(C-1)&C 得到最后一个非零位置组成的数 
如C = 1100, 算出来的结果是0100.

因此代码如下(大同小异)

 public int[] SingleNumber(int[] nums)
        {
            int n = nums.Length;
            //res存放两个出现单次的数的异或结果,比如a和b
            int res = nums[0];
            for (int i = 1; i < n; i++)
                res ^= nums[i];

            //找到res中第1个1的位置,因为a!=b,所以肯定至少有一个是1,然后根据这个位是否为1将numns拆成两组,再分别异或
            int lastOneVal = res - res & (res - 1);

            int[] num = new int[2] { 0, 0 };
            for (int i = 0; i < n; i++)
            {
                if ((nums[i] & lastOneVal) == 0)
                    num[0] ^= nums[i];
                else
                    num[1] ^= nums[i];
            }
            return num;
        }


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值