Single Number 系列

Single Number I

  • 题目:有一个数据只出现一次,其他数据都出现两次
  • 思路:位运算(亦或),只要循环异或,出现两次的都变成0了,最后只剩下出现一次的single number
  • 异或解释
  1. 按位异或运算符“^”是双目运算符。
  2. 功能是参与运算的两数各对应的二进位相异或。
  3. 当两个对应的二进制位相异时,结果为1
  4. 例如9^5 可写成算式如下:00001001^00000101
  5. 结果为00001100 (十进制为12)
public class Solution {
    public int singleNumber(int[] nums) {
        int result=0;
        for(int i=0;i<nums.length;i++){
            result^=nums[i];
        }
        return result;
    }
}

Single Number II

  • 题目:有一个数据只出现一次,其他数据均出现3次
  • 思路:位运算

由于只有一个出现一次的数字,其余数字都是出现三次
针对于序列中出现三次的所有数字的每一位来说,相加的结果只有两种:1+1+1==3 或者0+0+0=0
所以加上只出现一次的数字的对应位数字的话,结果有两种:0或4
所以对上述的每一位求和之后对3取余,结果为:1或0
当结果为1的时候,也就是这个位上出现了只出现一次的数字

  • 按位或运算
  1. 功能是参与运算的两数各对应的二进位相或。
  2. 只要对应的二个二进位有一个为1时,结果位就为1。
  3. 例如:9|5可写算式如下: 00001001|00000101
  4. 结果为:00001101 (十进制为13)
    也就是9|5=13
public class Solution {
    public int singleNumber(int[] nums) {
        if(nums == null||nums.length == 0){
            return -1;
        }
        //得到出现一次的数字的值
        int result=0;
        //int为4字节,那么共有32位
        for(int i=0;i<32;i++){
            //保存每一位求和值
            int sum=0;
            for(int j=0;j<nums.length;j++){
                //累加所有数字上第i位的数字
                sum+=(nums[j]>>i)&1;
                //System.out.println("sum"+sum);
            }
            //取余得到第i位上的数字,更新result
            result|=(sum%3)<<i;
            //System.out.println("res+"+result);
        }
        return result;
    }
}

Single Number III

  • 题目:数组中只出现一次的两个数字
  • 思路:
  1. 异或思想,一个数与自己异或为0,一个数与0异或为自己
  2. 由于其它数字两两相同,所以所有数异或则得到这两个不同数的异或结果。取这个结果的第一个1作为标志位
  3. 这个标志的1,必须是:这两个数在该位一个为0,一个为1,因为是异或操作,结果为1必然在这里两个数字一个为0一个为1
  4. 这里的结果必须是会产生的,也就是说肯定存在异或结果为1,不然这两个数字就是相等的
  5. 这样可以将数组分为两组,一组在该标志位为1,一组在该标志位为0,这两个不同数字分别在这两组内
  6. 将两组内的数分别异或,得到两个结果则为这两个不同的数
public class Solution {
    public int[] singleNumber(int[] nums) {
        int[] res=new int[2];
        if(nums == null||nums.length == 0){
            res[0]=0;
            res[1]=0;
            return res;
        }
        int sum=0;
        for(int i=0;i<nums.length;i++){
            sum^=nums[i];
        }
        int count=0;
        while ((sum&1)==0){
            sum>>=1;
            count++;
        }
        res[0]=0;
        res[1]=0;
        for(int i=0;i<nums.length;i++){
            if((nums[i]&(1<<count))==0){
                res[0]^=nums[i];
            }else{
                res[1]^=nums[i];
            }
        }
        return res;
    }
}

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 121,758评论 17 134
  • 第2章 基本语法 2.1 概述 基本句法和变量 语句 JavaScript程序的执行单位为行(line),也就是一...
    枫叶appiosg阅读 2,974评论 0 13
  • 1.ios高性能编程 (1).内层 最小的内层平均值和峰值(2).耗电量 高效的算法和数据结构(3).初始化时...
    欧辰_OSR阅读 24,423评论 8 239
  • 前言:作为一名android开发人员,网络数据都是web开发人员提供,每次让他们写一个接口都跟求神拜佛一样,与其求...
    王小贱_ww阅读 1,510评论 0 1
  • 吃得饱饱的一天 女生节快乐啊各位 之前和朋友玩了狼人杀,虽然我很喜欢玩,但每一次玩我都会陷入对自己智商的无限沮丧和...
    披着马甲写日记阅读 80评论 0 0