Leetcode136.只出现一次的数字(3种解法)

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

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

作者:力扣 (LeetCode)
链接:https://leetcode-cn.com/leetbook/read/top-interview-questions/xm0u83/
来源:力扣(LeetCode) 

 法一:
如果数组长度为1,则返回第一个。
如果长度大于0:判断每个元素是否既不等于前一个也不等于后一个,若是则返回这个元素。第一个和最后一个元素单独判断(否则会溢出)

执行用时:6ms,在所有Java提交中击败了29.62%的用户
内存消耗:38.7MB,在所有Java提交中击败了25.30%的用户
法二:使用异或运算,将所有值进行异或
异或运算,相异为真,相同为假,所以 a^a = 0 ;0^a = a
因为异或运算 满足交换律 a^b^a = a^a^b = b 所以数组经过异或运算,单独的值就剩下了
由于异或运算中,a和a异或之后为0,0和b异或之后是b,又满足交换律,相当于把相同的数字都放到前面,异或之后全部变成0,这个0与放在最后那个唯一的数异或,就得到原数。

执行用时:1ms,在所有Java提交中击败了100.00%的用户
内存消耗:38.4MB,在所有Java提交中击败了85.04%的用户
法三:使用set
如果插入失败就说明重复,删除set中原来插入的这个数字,最后set中只剩下唯一的那个数字
执行用时:9ms,在所有Java提交中击败了20.13%的用户
内存消耗:38.7MB,在所有Java提交中击败了25.30%的用户

package 数组;

import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;

public class 只出现一次的数字_136 {
    /*
    法一:
    如果数组长度为1,则返回第一个。
    如果长度大于0:判断每个元素是否既不等于前一个也不等于后一个,若是则返回这个元素。第一个和最后一个元素单独判断(否则会溢出)
    执行用时:6ms,在所有Java提交中击败了29.62%的用户
    内存消耗:38.7MB,在所有Java提交中击败了25.30%的用户
     */
    public static int singleNumber(int[] nums) {
        Arrays.sort(nums);
        if(nums.length==1)
            return nums[0];
        if(nums[0]!=nums[1])
            return nums[0];
        if(nums[nums.length-1]!=nums[nums.length-2])
            return nums[nums.length-1];
        for(int i=1;i<nums.length-2;i++){
            if(nums[i]!=nums[i+1]&&nums[i]!=nums[i-1])
                return nums[i];
        }
        return 0;
    }
/*
法二:
使用异或运算,将所有值进行异或
异或运算,相异为真,相同为假,所以 a^a = 0 ;0^a = a
因为异或运算 满足交换律 a^b^a = a^a^b = b 所以数组经过异或运算,单独的值就剩下了
由于异或运算中,a和a异或之后为0,0和b异或之后是b,又满足交换律,相当于把相同的数字都放到前面,异或之后全部变成0,这个0与放在最后那个唯一的数异或,就得到原数。
执行用时:1ms,在所有Java提交中击败了100.00%的用户
内存消耗:38.4MB,在所有Java提交中击败了85.04%的用户
*/
    public int singleNumber2(int[] nums) {
        int reduce = 0;
        for (int num : nums) {
            reduce =  reduce ^ num;
        }
        return reduce;
    }
/*
法三:
使用set,如果插入失败就说明重复,删除set中原来插入的这个数字,最后set中只剩下唯一的那个数字
执行用时:9ms,在所有Java提交中击败了20.13%的用户
内存消耗:38.7MB,在所有Java提交中击败了25.30%的用户
 */
    public int singleNumber3(int[] nums) {
        Set<Integer> set = new HashSet<>();
        for (int num : nums) {
            if (!set.add(num)) {
                //如果添加失败,说明这个值在集合Set中存在,要把他给移除掉
                set.remove(num);
            }
        }
        //最终集合Set中只有一个元素,直接返回
        return (int) set.toArray()[0];
    }

    public static void main(String[] args) {
        int []a={1,2,2,1,3,4,4};
        System.out.println(singleNumber(a));
    }
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值