美文网首页数据结构和算法分析程序员
leecode刷题(5)-- 只出现一次的数字

leecode刷题(5)-- 只出现一次的数字

作者: 希希里之海 | 来源:发表于2019-01-16 13:41 被阅读44次

    leecode刷题(5)-- 只出现一次的数字

    只出现一次的数字

    描述:

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

    说明:

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

    示例:

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

    思路:

    因为“除了某个元素只出现一次一次,其余每个元素均出现两个”,所以如果该数组有序,且有一个元素只出现一次,以步数2向后遍历,那么一定会存在a[i] != a[i+1]。所以我们可以将数组排序,然后隔两个元素比较一次,看相邻元素的值是否相等,若不相等,即为我们要找得出现一次的数字。

    因为我们这里用到了排序,排序的时间复杂度为 O(nlogn),不是线性时间复杂度 O(n),其实并不是很好。

    代码如下:

    import java.util.Arrays;
    
    public class SingleNumber {
        public int singleNumber(int[] nums) {
            if (nums.length == 0) {
                return -1;
            }
            if (nums.length == 1) {
                return nums[0];
            }
    
            Arrays.sort(nums);
            for (int i = 0; i < nums.length; i += 2) {
                if (i == nums.length - 1) {
                    return nums[i];
                }
                if (nums[i] != nums[i + 1]) {
                    return nums[i];
                }
            }
            return 0;
        }
    
        public static void main(String[] args) {
            int[] nums = {2,2,4,3,3};
            SingleNumber singleNumber = new SingleNumber();
            int a = singleNumber.singleNumber(nums);
            System.out.println(a);
        }
    }
    

    改进:

    我们可以使用异或的方法,便能很完美的解决这个问题。

    所谓异或,即为:参与运算的两个元素,两者的值不同返回true,两者的值相同返回false。

    通过学习计算机基础,我们知道异或表达式有几个规律:

    1. 恒定律:A ^ 0 = A
    2. 归零率:A ^ A = 0
    3. 交换律:A ^ B = B ^ A
    4. 结合律:(A ^ B) ^ C = A ^ (B ^ C)

    这里我们举个例子:

    比如我们的数组为:{2,3,2,3,1}

    我们使用异或运算:

      2^3^2^3^1
    = 2^2^3^3^1
    = 0^0^1
    = 1
    

    所以看到这里,大家是不是懂了,我们让数组中的元素做异或运算,结果便为要找的 ”只出现一次的数字“。

    代码如下:

    import java.util.Arrays;
    
    public class SingleNumber {
        public int singleNumber(int[] nums){
            if (nums.length == 0) {
                return -1;
            }
            if (nums.length == 1) {
                return nums[0];
            }
    
            int result = 0;
            for (int i =0; i < nums.length; i++) {
                result = result ^ nums[i];
            }
            return result;
        }
    
        public static void main(String[] args) {
            int[] nums = {2,2,4,3,3};
            SingleNumber singleNumber = new SingleNumber();
            int a = singleNumber.singleNumber(nums);
            System.out.println(a);
        }
    }
    

    可以看到,时间复杂度为 O(n),符合题目线性时间复杂度的要求。

    相关文章

      网友评论

        本文标题:leecode刷题(5)-- 只出现一次的数字

        本文链接:https://www.haomeiwen.com/subject/phhmdqtx.html