136.只出现一次的数字

Posted still-smile

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了136.只出现一次的数字相关的知识,希望对你有一定的参考价值。

给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。

说明:你的算法应该具有线性时间复杂度。 你可以不使用额外空间来实现吗?

示例 1:

输入: [2,2,1]
输出: 1

示例 2:

输入: [4,1,2,1,2]
输出: 4


1.暴力法:排序后,以sizeof(int)*2为一个单元来遍历,当发现一个单元内的两个数字不同,输出该单元第一个数字。

int cmpfunc (const void * a, const void * b)
{
   return ( *(int*)a - *(int*)b );
}

int singleNumber(int* nums, int numsSize)
{
if(numsSize==1) return nums[0]; qsort(nums, numsSize, sizeof(int), cmpfunc); for(int j = 0; j <numsSize-1 ; j+=2 ) { if(nums[j]!=nums[j+1]) { return nums[j]; } } return nums[numsSize-1]; }

2.异或法

①运用异或运算的交换律

即:a^b^c^d=a^c^d^b ,任意交换位置,结果都相等

②运用异或运算的本质

即:a^a=0,0^a=a

int singleNumber(int* nums, int numsSize)
{
  int sum = nums[0];   for(int i = 1;i < numsSize;i++)
  {     sum
^= nums[i];   }   return sum; }

3.递归异或法:

核心要义,从数组最后一个元素开始异或到第一个元素,

擦边球:最先return的是numsSize=1,在这一层,由于该三目运算符的特性,并不会计算后面那个非法调用的函数,但语法规则是合法的。

实际上这种办法比方法②还要糟糕,甚至有时候比方法①还要糟糕,递归调用需要消耗大量函数栈,也就是栈空间,不过看上去是相当华丽。

int singleNumber(int* nums, int numsSize)
{
  return numsSize==1?nums[0]:(singleNumber(nums+1,numsSize-1)^nums[0]); }

4.hash:

这里实现hash的关键是a[nums[i]-min]这一步,可以保证a数组的下标都为正。出现两次的位置的元素都会是累加两次,没出现的位置为0,仅出现一次的地方只会累加一次。

int singleNumber(int* nums, int numsSize){
    if(numsSize == 1)
    return nums[0];

    int i = 0;
    int max = nums[0];
    int min = nums[0];

    for(i = 0; i<numsSize; i++)
    {
        max = max > nums[i]? max:nums[i];
        min = min < nums[i]? min:nums[i];
    }
    max = max-min+1;
    int a[max];//声明一个考虑了最坏情况的最小数组,来承接数字
    memset(a,0,sizeof(int)*(max));
    for(i = 0; i<numsSize; i++)
    {
        a[nums[i]-min] += 1;
    }
    for(i = 0; i < numsSize; i++)
    {
        if(a[nums[i]-min] == 1)
        {
            return nums[i];
        }
    }
    return 0;
}

总结:出现概率型+数组的问题,首先考虑hash,其次考虑运算特性。

以上是关于136.只出现一次的数字的主要内容,如果未能解决你的问题,请参考以下文章

[leetcode]136. 只出现一次的数字

p6 只出现一次的数字 (leetcode136)

LeetCode 136. 只出现一次的数字

LeetCode 136. 只出现一次的数字

LeetCode 136. 只出现一次的数字

leetcode136 只出现一次的数字(Easy)