zoukankan      html  css  js  c++  java
  • 【LeetCode】136. Single Number

    题目:

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

    例1:

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

    例2:

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

    思路:

    对数组元素进行依次统计,如果一个元素已经出现了两次,则不再关注,直到找到只出现一次的元素。

    #include <stdio.h>
    
    //统计在数组arr中数字k出现的次数,n是数组的大小
    int countLetter(int* arr, int n, int k) {
        int count = 0;
        for (int i=0; i<n; i++) {
            if (arr[i] == k) {
                count++;
            }
        }
        return count;
    }
    
    int singleNumber(int* nums, int numsSize) {
        for (int i=0; i<numsSize; i++) {
            int count = countLetter(nums, numsSize, nums[i]);
            if (count == 1)
                return nums[i];
        }
        return 0;
    }
    
    int main()
    {
        int nums[] = {5, 8, 5, 6, 8, 7, 7};
        int number = singleNumber(nums, 7);
        printf("The single number is %d.
    ", number);
    }

    结果:

    系统虽然接受了这个程序,但是运行时间长达400ms,排名也十分靠后。

    很明显是时间上吃了亏。在这个程序中,singleNumber函数中有一个for循环,在这个for循环中调用了countLetter函数,而countLetter函数中也有一个for循环,这样时间复杂度就达到了O(n2),这样的时间复杂度太高了。

    所以要想改进的话就要从时间复杂度来入手了


    改进思路:

    用异或的性质

    异或有交换性,还有一个很有意思的性质,a^b^b=a,即数a两次异或同一个数b(a=a^b^b)仍然为原值a。又如:a^b^a^c^b^c^d=d。

    令k等于数组中任意一个数字,并与剩余元素进行异或运算,最后结果就是那个single number。

    #include <stdio.h>
    
    int singleNumber(int* nums, int numsSize) {
        int k = nums[0];
        for (int i=1; i<numsSize; i++) {
            k = (k ^ nums[i]);
        }
        return k;
    }
    
    int main()
    {
        int nums[] = {5, 6, 5, 6, 8, 7, 7};
        int number = singleNumber(nums, 7);
        printf("The single number is %d.
    ", number);
    }

    结果:

    这次运行时间为4ms,相比400ms效率不知道高到哪里去了,排名自然也非常靠前。

    异或还有一些其他有意思的性质,比如可以在不引入临时变量的情况下交换两个变量的值等等。

    a=10100001,   b=00000110
    
    a=a^b; //a=10100111
    
    b=b^a; //b=10100001
    
    a=a^b; //a=00000110

    参考:一起玩算法02

    推荐一位干货up主:正月点灯笼

  • 相关阅读:
    《数据结构》C++代码 线性表
    《数据结构》C++代码 Splay
    《数据结构》C++代码 前言
    蓝桥杯- 算法提高 最大乘积
    HDU-1241 Oil Deposits
    一个简单的网站计数器
    编写一个jsp页面,输出九九乘法表。
    Sum It Up
    历届试题 剪格子
    历届试题 分糖果
  • 原文地址:https://www.cnblogs.com/ME-WE/p/12433598.html
Copyright © 2011-2022 走看看