[LeetCode]--136. 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

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?

耐心看下我的思想演变过程吧,可能是大脑缺氧,用List装下标。

public int singleNumber(int[] nums) {
        if (nums.length == 1)
            return nums[0];
        ArrayList<Integer> temp = new ArrayList<Integer>();
        for (int i = 0; i < nums.length - 1; i++) {
            if (temp.contains(i))
                continue;
            for (int j = i + 1; j < nums.length; j++) {
                if (temp.contains(j))
                    continue;
                if (nums[i] == nums[j]) {
                    System.out.println(i + "---" + j);
                    temp.add(i);
                    temp.add(j);
                    break;
                }
            }
        }
        for (int i = 0; i < nums.length; i++) {
            if (!temp.contains(i)) {
                return nums[i];
            }
        }
        return 0;
    }

代码逻辑和实现应该没有问题,测试也通过了,就是提交的时候超时了,于是我就想着用空间去换取时间。

public int singleNumber1(int[] nums) {
        ArrayList<Integer> preList = new ArrayList<Integer>();
        ArrayList<Integer> list = new ArrayList<Integer>();
        int len = nums.length;
        int[] flag = new int[len];
        Arrays.fill(flag, 0);
        for (int i = 0; i < len; i++) {
            if (!preList.contains(nums[i])) {
                preList.add(nums[i]);
            } else {
                flag[i] = 1;
            }
            if (!list.contains(nums[len - 1 - i])) {
                list.add(nums[len - 1 - i]);
            } else {
                flag[len - 1 - i] = 1;
            }
        }
        for (int i = 0; i < flag.length; i++) {
            if (flag[i] == 0) {
                return nums[i];
            }
        }
        return 0;
    }

这也是一种方法其实,两头同时遍历,一次遍历就可以解决问题,但是仔细想想其实复杂度没减。

再使用暴力搜索,遍历数组,发现两个元素相等,则将这两个元素的标志位置为1,最后返回标志位为0的元素即可。时间复杂度O(n^2)没有AC,Status:Time Limit Exceed

public int singleNumber2(int[] nums) {
        int n = nums.length;
        if (n == 1)
            return nums[0];
        int[] flag = new int[n];
        for (int i = 0; i < n; i++) {
            if (flag[i] == 1)
                continue;
            else {
                for (int j = i + 1; j < n; j++) {
                    if (nums[i] == nums[j]) {
                        flag[i] = 1;
                        flag[j] = 1;
                    }
                }
            }
        }
        for (int i = 0; i < n; i++) {
            if (flag[i] == 0)
                return nums[i];
        }
        return 0;
    }

后来用这个就是通过的,Accept!真是高兴,但是又不服,这个其实和第一次一样,只是用数组装flag。而且我觉得很有可能是偶然通过的。

其实我记得有个位运算很简单也很高效。但是说实话,一般来说大家对位运算都有种神秘陌生对吧,我也不例外,虽然知道,但是用起来很困难。

利用异或操作。异或的性质1:交换律a ^ b = b ^ a,性质2:0 ^ a = a。于是利用交换律可以将数组假想成相同元素全部相邻,于是将所有元素依次做异或操作,相同元素异或为0,最终剩下的元素就为Single Number。时间复杂度O(n),空间复杂度O(1)

public int singleNumber(int[] A) {
        if(A == null || A.length == 0) {
            return -1;
        }
        int rst = 0;
        for (int i = 0; i < A.length; i++) {
            rst ^= A[i];
        }
        return rst;
    }

所以还是强烈建议用后面这种。

目录
相关文章
|
算法
Leetcode 313. Super Ugly Number
题目翻译成中文是『超级丑数』,啥叫丑数?丑数就是素因子只有2,3,5的数,7 14 21不是丑数,因为他们都有7这个素数。 这里的超级丑数只是对丑数的一个扩展,超级丑数的素因子不再仅限于2 3 5,而是由题目给定一个素数数组。与朴素丑数算法相比,只是将素因子变了而已,解法还是和朴素丑数一致的。
104 1
|
6月前
|
存储 SQL 算法
LeetCode 题目 65:有效数字(Valid Number)【python】
LeetCode 题目 65:有效数字(Valid Number)【python】
|
7月前
|
存储 算法
【LeetCode力扣】单调栈解决Next Greater Number(下一个更大值)问题
【LeetCode力扣】单调栈解决Next Greater Number(下一个更大值)问题
51 0
|
存储
Leetcode Single Number II (面试题推荐)
给你一个整数数组,每个元素出现了三次,但只有一个元素出现了一次,让你找出这个数,要求线性的时间复杂度,不使用额外空间。
39 0
LeetCode contest 190 5417. 定长子串中元音的最大数目 Maximum Number of Vowels in a Substring of Given Length
LeetCode contest 190 5417. 定长子串中元音的最大数目 Maximum Number of Vowels in a Substring of Given Length
LeetCode Contest 178-1365. 有多少小于当前数字的数字 How Many Numbers Are Smaller Than the Current Number
LeetCode Contest 178-1365. 有多少小于当前数字的数字 How Many Numbers Are Smaller Than the Current Number
LeetCode 136. 只出现一次的数字 Single Number
LeetCode 136. 只出现一次的数字 Single Number
|
3月前
|
Unix Shell Linux
LeetCode刷题 Shell编程四则 | 194. 转置文件 192. 统计词频 193. 有效电话号码 195. 第十行
本文提供了几个Linux shell脚本编程问题的解决方案,包括转置文件内容、统计词频、验证有效电话号码和提取文件的第十行,每个问题都给出了至少一种实现方法。
LeetCode刷题 Shell编程四则 | 194. 转置文件 192. 统计词频 193. 有效电话号码 195. 第十行
|
4月前
|
Python
【Leetcode刷题Python】剑指 Offer 32 - III. 从上到下打印二叉树 III
本文介绍了两种Python实现方法,用于按照之字形顺序打印二叉树的层次遍历结果,实现了在奇数层正序、偶数层反序打印节点的功能。
59 6
|
4月前
|
搜索推荐 索引 Python
【Leetcode刷题Python】牛客. 数组中未出现的最小正整数
本文介绍了牛客网题目"数组中未出现的最小正整数"的解法,提供了一种满足O(n)时间复杂度和O(1)空间复杂度要求的原地排序算法,并给出了Python实现代码。
121 2