leetcode136.只出现一次的数字,137.只出现一次的数

2020-06-02  本文已影响0人  憨憨二师兄

leetcode136.只出现一次的数字

题目链接

题目描述:

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

说明:

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

示例 1:

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

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

思路:异或运算

对于异或运算有以下特性:

  1. a ^ a = 0
  2. a ^ 0 = a

已知非空数组中,只有某个元素出现了一次,其余的元素均出现了两次。所以,我们可以从头让每个元素依次进行异或运算,一直遍历到最后一个元素,异或的结果就是那个只出现一次的元素。代码如下:

class Solution {
    public int singleNumber(int[] nums) {
        int res = 0;
        for(int i = 0; i < nums.length; ++i){
            res ^= nums[i];
        }
        return res;
    }
}

时间复杂度:O(N)
额外空间复杂度:O(1)

代码执行结果:


leetcode 137.只出现一次的数字ii

题目链接

题目描述:

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

说明:

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

示例 1:

输入: [2,2,3,2]
输出: 3
示例 2:

输入: [0,1,0,1,0,1,99]
输出: 99

思路:位运算

对于题目的示例:

[2,2,3,2]

转换为二进制后:

10
10
11
10

每一位上对1的个数进行统计,如果能整除3,那么返回结果的那一位则为0;如果不能整除3,那么返回结果的那一位则为1:

10
10
11
10

第一位的和为1,第二位的和为4,都不能整除3,所以结果为:
11

返回的结果转换为十进制后,也正好为只出现一次的那个元素

代码如下:

class Solution {
    public int singleNumber(int[] nums) {
        int res = 0;
        for(int i = 0;i < 32;i++){
            int temp = 0;
            for(int num : nums){
                temp += (num >>> i) & 1;
            }
            if(temp % 3 != 0){
                res |= (1 << i);
            }
        }
        return res;
    }
}

时间复杂度:O(N)
额外空间复杂度:O(1)

代码执行结果:


上一篇 下一篇

猜你喜欢

热点阅读