HelloCoder HelloCoder
首页
《Java小白求职之路》
《小白学Java》
计算机毕设
  • 一些免费计算机资源
  • 脚手架工具
  • 《从0到1学习Java多线程》
  • 《从0到1搭建服务器》
  • 《可观测和监控》
随笔
关于作者
首页
《Java小白求职之路》
《小白学Java》
计算机毕设
  • 一些免费计算机资源
  • 脚手架工具
  • 《从0到1学习Java多线程》
  • 《从0到1搭建服务器》
  • 《可观测和监控》
随笔
关于作者
  • 《LearnJavaToFindAJob》

    • 导读

    • 【初级】6~12k档

    • 【中级】12k-26k档

      • JVM进阶

      • Java进阶

      • MySQL

      • 中间件

      • 算法

        • 1-两数之和
        • 高频算法面试题
        • 2两数相加
        • 09-用两个栈实现一个队列
        • 11-盛水最多的容器
        • 19-删除链表的倒数第N个结点
        • 20-有效的括号
        • 22-括号生成
        • 39-组合总和
        • 46-全排列
        • 53-连续最大子序和
        • 64匹马,只有8个赛道,挑选出最快的4匹马
        • 70-爬楼梯
        • 136-只出现一次的数字
        • 141环形链表
        • 206-翻转链表
        • 234回文链表
        • 387-字符串中的第一个唯一字符
        • 543二叉树最大直径
        • 八大排序算法
        • 剪绳子
        • 旋转数
        • 模板
        • 求解立方根不使用库函数
      • 高阶

    • 【高级】26k+档

    • 大厂面试题

    • 求职建议

    • 面经

  • LearnJavaToFindAJob
  • 【中级】12k-26k档
  • 算法
#只出现一次 #数字
码农阿雨
2022-06-02
目录

136-只出现一次的数字

# 描述

难度:简单

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

说明:

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

示例 1:

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

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

来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/single-number 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

# 思路

LeetCode入门最简单,也是最经典的题目之一,解决方法会有很多。

我觉得这道题最重要的掌握不同的方法,发散思维,然后明白时间复杂度、空间复杂度如何计算,所以入门算法的筒子们,可以看看这道题,慢慢琢磨。

# 方法一:暴力循环

两次循环,先指定第1个数,然后再遍历整个数组,如果没找到除了自己的数之外,就返回该数据。

但是时间复杂度高。

* 时间复杂度:O(n^2)
* 空间复杂度:O(1)

# 方法二:hashSet

既然这样,最容易想到的方法就是把所有的元素放到hashSet里面,全部add进去,然后add返回false的时候(证明已经add过了,表示出现了两次)再remove一次,最后hashSet里面就是只出现一次的数了。

* 时间复杂度:O(n)
* 空间复杂度:O(n)

虽然时间复杂度降下来了,却需要用到额外的空间。

# 方法三:先排序再比较

把数组全部排序后,再比较,n和n+1的元素,如果不相等,表示 n 就是只出现一次的元素了。

* 时间复杂度:O(n) 要看排序方法
* 空间复杂度:O(1)

# 方法四:异或

异或 ^,相同 则为 0,不相同 则为1。所以两个相同的数异或都会等于0,任何数和 0 异或,都是等于本身。所以只要把数组所有的数进行异或,得到的就会是只出现一次的元素。

* 时间复杂度:O(n)
* 空间复杂度:O(1)

# 题解

public class 只出现一次的数字136 {
    public static void main(String[] args) {
//        int[] nums = new int[]{2, 2, 1};
        int[] nums = new int[]{4, 1, 2, 1, 2};
        System.out.println(singleNumber1(nums));
        System.out.println(singleNumber2(nums));
    }

    /**
     * 暴力循环
     * 时间复杂度:O(n^2)
     * 空间复杂度:O(n)
     */
    static int singleNumber1(int[] nums) {
        for (int i = 0; i < nums.length; i++) {
            boolean flag = true;
            for (int j = 0; j < nums.length; j++) {
                if (nums[i] == nums[j] && i != j) {
                    flag = false;
                    break;
                }
            }
            if (flag) {
                return nums[i];
            }
        }
        return -1;
    }

    /**
     * hashSet
     * 时间复杂度:O(n)
     * 空间复杂度:O(n)
     */
    public static int singleNumber2(int[] nums) {

        Set<Integer> set = new HashSet<>();
        for (int i = 0; i < nums.length; i++) {
            // 尝试将当前元素加入 set
            boolean flag = set.add(nums[i]); //false 表示无法add,即已存在
            if (!flag) {
                // 当前元已经存在于 set,即当前元素第二次出现,从 set 删除
                set.remove(nums[i]);
            }
        }
        // 最后只剩一个不重复的元素
        return set.iterator().next();
    }

    /**
     * 先排序再移位,
     * 时间复杂度:O(n) 要看排序方法
     * 空间复杂度:O(1)
     */
    static int singleNumber3(int[] nums) {
        Arrays.sort(nums);
        for (int i = 0; i < nums.length; ) {
            if (i + 1 < nums.length && (nums[i] == nums[i + 1])) { //如果是最后一位则不能i+1
                i = i + 2;
            } else {
                return nums[i];
            }
        }
        return -1;
    }

    /**
     * 异或,任何和0异或的数,都是原来的数
     * 时间复杂度:O(n)
     * 空间复杂度:O(1)
     */
    static int singleNumber4(int[] nums) {
        int single = 0;
        for (int num : nums) {
            single ^= num;
        }
        return single;
    }
}
阅读全文
×

(为防止恶意爬虫)
扫码或搜索:HelloCoder
发送:290992
即可永久解锁本站全部文章

解锁
#只出现一次#数字
上次更新: 2026-03-28 17:00:16
最近更新
01
MySQL支持的锁有哪些
03-28
02
HTTP 是不保存状态的协议, 如何保存用户状态
03-28
03
用户态和内核态的区别
03-28
更多文章>
Theme by Vdoing | Copyright © 2020-2026 码农阿雨
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式