本文属于「征服LeetCode」系列文章之一,这一系列正式开始于2021/08/12。由于LeetCode上部分题目有锁,本系列将至少持续到刷完所有无锁题之日为止;由于LeetCode还在不断地创建新题,本系列的终止日期可能是永远。在这一系列刷题文章中,我不仅会讲解多种解题思路及其优化,还会用多种编程语言实现题解,涉及到通用解法时更将归纳总结出相应的算法模板。

为了方便在PC上运行调试、分享代码文件,我还建立了相关的仓库:https://github.com/memcpy0/LeetCode-Conquest。在这一仓库中,你不仅可以看到LeetCode原题链接、题解代码、题解文章链接、同类题目归纳、通用解法总结等,还可以看到原题出现频率和相关企业等重要信息。如果有其他优选题解,还可以一同分享给他人。

由于本系列文章的内容随时可能发生更新变动,欢迎关注和收藏征服LeetCode系列文章目录一文以作备忘。

Given a non-empty 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?

Example 1:

Input: [2,2,1]
Output: 1

Example 2:

Input: [4,1,2,1,2]
Output: 4

Example 3:

Input: nums = [1]
Output: 1

Constraints:

  • 1 ≤ nums.length ≤ 3 * 104
  • -3 * 104 ≤ nums[i] ≤ 3 * 104
  • Each element in the array appears twice except for one element which appears only once.

题意:给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。你的算法应该具有线性时间复杂度。 你可以不使用额外空间来实现吗?


解法1 哈希表(额外空间)

朴素的做法是,利用哈希表或整型数组(不是很优雅)进行统计,最后返回出现一次的元素。时间复杂度为 O(2n)O(2n)O(2n) ,空间复杂度为 O(n)O(n)O(n) :

//C++ version
class Solution {public:int singleNumber(vector<int>& nums) {int rec[60010] = {0};for (int i = 0, n = nums.size(); i < n; ++i) ++rec[nums[i] + 30000];for (int i = 0; i < 60010; ++i) if (rec[i] == 1) return i - 30000; return 0;}
};
//执行用时:16 ms, 在所有 C++ 提交中击败了72.90% 的用户
//内存消耗:16.7 MB, 在所有 C++ 提交中击败了12.32% 的用户
//Java version
class Solution {public int singleNumber(int[] nums) {Map<Integer, Integer> rec = new HashMap<>();for (int v : nums) rec.put(v, rec.getOrDefault(v, 0) + 1);for (int v : rec.keySet())if (rec.get(v) == 1) return v;return 0;}
}
//执行用时:14 ms, 在所有 Java 提交中击败了6.05% 的用户
//内存消耗:39.1 MB, 在所有 Java 提交中击败了5.54% 的用户

解法2 位运算(最优)

最简单的方法是异或。利用「除答案外的元素均出现两次」的特性,对 nums[] 中的所有元素执行异或操作,得到的结果就是要求的答案。时间复杂度为 O(n)O(n)O(n) ,空间复杂度为 O(1)O(1)O(1) :

//C++ version
class Solution {public:int singleNumber(vector<int>& nums) {int ans = 0;for (auto &i : nums) ans ^= i;return ans;}
};
//执行用时:8 ms, 在所有 C++ 提交中击败了99.03% 的用户
//内存消耗:16.4 MB, 在所有 C++ 提交中击败了87.84% 的用户

另外一个版本的代码,利用了 Deff's Device 进行循环展开:

//C++ version
class Solution {public:int singleNumber(vector<int>& nums) {int ans = 0, cnt = nums.size(), n = (cnt + 7) / 8;vector<int>::iterator it = nums.begin();switch (cnt % 8) {case 0: do { ans ^= *it++;case 7:      ans ^= *it++;case 6:      ans ^= *it++;case 5:      ans ^= *it++;case 4:      ans ^= *it++;case 3:      ans ^= *it++;case 2:      ans ^= *it++;case 1:      ans ^= *it++;} while (--n > 0);}return ans;}
};
//执行用时:8 ms, 在所有 C++ 提交中击败了99.03% 的用户
//内存消耗:16.4 MB, 在所有 C++ 提交中击败了94.52% 的用户

如果用C语言的话:

int singleNumber(int* nums, int numsSize) {int ans = 0, n = (numsSize + 7) / 8;switch (numsSize % 8) {case 0: do { ans ^= *nums++;case 7:      ans ^= *nums++;case 6:      ans ^= *nums++;case 5:      ans ^= *nums++;case 4:      ans ^= *nums++;case 3:      ans ^= *nums++;case 2:      ans ^= *nums++;case 1:      ans ^= *nums++;} while (--n > 0);}return ans;
}
//执行用时:16 ms, 在所有 C 提交中击败了80.17% 的用户
//内存消耗:6.9 MB, 在所有 C 提交中击败了95.90% 的用户

LeetCode 136. Single Number【哈希表/位运算/数学】简单相关推荐

  1. 【异或】LeetCode 136. Single Number

    LeetCode 136. Single Number Solution1:我的答案 还好异或的性质没记错,还好,还好 class Solution { public:int singleNumber ...

  2. [勇者闯LeetCode] 136. Single Number

    [勇者闯LeetCode] 136. Single Number Description Given an array of integers, every element appears twice ...

  3. Leetcode 136 Single Number 仅出现一次的数字

    原题地址 https://leetcode.com/problems/single-number/ 题目描述 Given an array of integers, every element app ...

  4. leetcode 136. Single Number

    Given an array of integers, every element appears twice except for one. Find that single one. Note: ...

  5. [swift] LeetCode 136. Single Number

    Given an array of integers, every element appears twice except for one. Find that single one. Note: ...

  6. 0位运算/数学简单 剑指 Offer 65. 不用加减乘除做加法

    剑指 Offer 65. 不用加减乘除做加法 描述 写一个函数,求两个整数之和,要求在函数体内不得使用 "+"."-"."*"." ...

  7. 263.Ugly Number||202 happy number||476 Number Complement||136 Single Number

    263.Ugly Number 判断因数是否只有素数2.3.5.. 感觉比较简单: class Solution(object):def isUgly(self, num):""& ...

  8. 【?异或】LeetCode 260. Single Number III

    LeetCode 260. Single Number III Solution1: 博客转载自:http://www.cnblogs.com/grandyang/p/4741122.html 这道题 ...

  9. 【异或】LeetCode 137. Single Number II

    LeetCode 137. Single Number II Solution1:不会做,抄的 博客转载自:http://www.cnblogs.com/grandyang/p/4263927.htm ...

最新文章

  1. 标准C++中的string类的用法总结
  2. 大家眼中的桌面技术支持是什么样的?
  3. Harris算子的运用 用于图像配准
  4. 基于VUE的前端crypto-js aes加密与解密
  5. sql delete删除两个表_超强干货!SQL语法大合集
  6. 【快速入门ORM框架之Dapper】大牛勿进系列
  7. Not enough space in file systems for the current software selection. An additional XXXX MiB is neede
  8. 微波遥感SNAP(三)——检测地表沉降(1)自动化处理(Graph Builder)
  9. java 代码行数统计工具_代码行数统计工具
  10. 第一、二章 引论、算法分析
  11. 逆波兰表达式(Java)
  12. EM78P153单片机构成433MHz发射电路
  13. aspose设置两个word拼接后连续页码
  14. yum安装软件时报错:Errors during downloading metadata for repository ‘AppStream‘的处理
  15. Progressive Layered Extraction: A Novel Multi-TaskLearning Model for Personalized Recommendations
  16. 控制BLDC资料汇总
  17. 使用SQLyog导出导入MySql中的数据
  18. 谷歌地图高清卫星地图、电子地图和地形图有什么区别?
  19. 技术管理实战笔记-角色认知篇
  20. 中国液晶面板王者为何被小弟超越了?

热门文章

  1. 客户案例|地产行业如何做好销售过程管理,让赢单水到渠成?
  2. 每个Linux管理员应该知道的20个Linux系统监视工具
  3. MongoDB 客户端工具
  4. wap端开发必须基础
  5. 参与影视拍摄过程,感悟科学知识融合
  6. 7-3 公路村村通 (30分)含解析
  7. 闭门分享实录:100位产品经理“拷问”罗辑思维创始人快刀青衣
  8. 配置linux主机开启telnet服务
  9. 认清各种影视资源不同版本
  10. ELK搭建 - Docker篇