找出数组中只出现了一次的数字

  • 题目
  • 题目分析
    • 方法1
    • 方法2
    • 方法3
  • 代码实现
    • 主方法
    • 方法1
      • 第一种:使用计数器的
      • 第二种:不使用计数器
    • 方法2
    • 方法3
  • 总结

题目

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

  • 示例

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

题目分析

注意输入格式,在主方法中不能直接得到数组,应先定义字符串变量接收键盘输入,在使用String类的几种方法得到这个整数数组。
另外定义一个方法找只出现了一次的元素,这个方法返回值为int类型。在方法中,要找到那个元素,有以下解决方法:

方法1

最基本的方法就是双重循环遍历数组,可以直接找出只出现了一次的数,但是,显然这种方法时间复杂度高,效率低下

方法2

使用Set集合存储,Set集合不存储重复值,add()方法返回值为boolean类型,这一特点可以利用。
Set集合的add方法,添加成功返回true,否则返回false,而Set集合不存储重复值,所以当要添加的数与集合中已存在的数重复时,不会再进行添加操作,返回false,这时再进行remove操作,将集合中已存在的那个与要添加的数相同的元素移除,这样将作为方法参数传递过来的整型数组遍历完后,到最后集合中就只剩下了那个只出现了一次的数字。

方法3

使用异或运算符^,0与其他数字异或的结果是那个数字,相等的数字异或得0。要操作的数组中除了某个数字只出现了一次之外,其他数字都出现了两次,所以可以定义一个变量赋初始值为0,用这个变量与数组中每个数字做异或运算,并将这个变量值更新为那个运算结果,直到数组遍历完毕,最后得到的变量的值就是数组中只出现了一次的数字了。这种方法只需遍历一次数组,提高了程序运行的效率。

总结一下:这种解法要用到异或运算的几个规则:

  1. 0^0 = 0;
  2. 0^a = a;
  3. a^a = 0;
  4. a ^ b ^ a = b.

当然这些只是一部分,不过刚好够用,想要了解异或运算符的小伙伴可以去看看百度百科的介绍:异或运算

代码实现

主方法

public static void main(String[] args) {Scanner sc = new Scanner(System.in);String str = sc.nextLine();str = str.substring(1, str.length()-1);//去掉键盘输入的字符串中的"["和"]"String[] s = str.split(",");//将字符串以","分割,转为一个字符串数组int[] arr = new int[s.length];//定义一个整形数组,准备用来存数据了for(int i = 0; i < arr.length; i++)arr[i] = Integer.parseInt(s[i]);//将字符串转为int类型数据存入整型数组中System.out.println(Find_Num(arr));//调方法}

注:这里直接将字符串转为整型数据使用的是包装类Integer类的parseInt()静态方法,调用时直接类名调用,方法返回值为Integer类型,但是可以自动拆箱为int型,因此用int或Integer类型接收均可。
另外,注意一下主方法中没有对方法返回值进行判断而直接做了输出,也就是说不考虑那个数字不出现的情况

方法1

第一种:使用计数器的

public static Integer Find_Num_1(int[] arr){for(int i = 0; i < arr.length; i++) {int count = 1;//计数器for(int j = 0; j < arr.length; j++) {if(i == j)continue;//下标相等则直接进入下一次循环if(arr[i] == arr[j])count++;//如果不同下标的数组元素相等,则计数器加1}if(count == 1)return arr[i];//返回只出现了一次的元素}return null;//找不到则返回null}

第二种:不使用计数器

public static Integer Find_Num_1(int[] arr){for(int i = 0; i < arr.length; i++){for(int j = 0; j <= arr.length; j++){//注意循环结束的条件,实际运行时j不会超出数组范围if(i == j)continue;if(j == arr.length)//因为这里的判断,让代码运行时在超出范围前就结束了循环return arr[i];if(arr[i] == arr[j])break;}}return null;//找不到则返回null}

可能已经有人注意到,方法1中两段代码方法的返回值为Integer类型,这样就方便了在没有找到时返回null作为标志

方法2

public static int Find_Num_2(int[] arr) {Set<Integer> set = new HashSet<Integer>();//创建Set集合for(int i : arr) {//增强for循环遍历数组if(!set.add(i))//添加不成功返回false,前加上!运算符变为trueset.remove(i);//移除集合中与这个要添加的数重复的元素}return set.toArray(new Integer[set.size()])[0];//返回它转为Integer数组后数组的第一个元素}

使用时要注意前提,必须存在那个只出现了一次的数字,否则Set集合长度将为0,最后一句代码运行时出错,改进一下的话,就像方法1那样,将返回值类型设置为Integer:

public static Integer Find_Num_2(int[] arr) {Set<Integer> set = new HashSet<Integer>();//创建Set集合for(int i : arr) {//增强for循环遍历数组if(!set.add(i))//添加不成功返回false,前加上!运算符变为trueset.remove(i);//移除集合中与这个要添加的数重复的元素}if(set.size() == 0)    return null;//如果Set集合长度为0,返回null表示没找到return set.toArray(new Integer[set.size()])[0];}

方法3

public static int Find_Num_3(int[] arr) {int flag = 0;for(int i : arr) {flag ^= i;}return flag;}

这段代码的问题在于,如果用户输入了偶数个数的数据,方法将返回0值,而当这个只出现了一次的数字为0时,方法当然也返回0,所以使用前提是必须存在一个只出现了一次的数字

总结

需要注意的是: 这个题的前提条件是这个只出现了一次的数字是存在的,那么使用时在输入阶段需要用户注意到这个问题,输入的数据个数只能是奇数,否则在使用方法3时会出现答案错误的情况,而方法1和改进后的方法2可以正常使用,如果输出为null代表着没有找到。

找出数组中只出现了一次的数字(Java)相关推荐

  1. 找出数组中只出现一次的数

    case1 一个整形数组中除了一个数字之外,其他数字都出现了两次,请找出这个数.要求时间复杂度O(n),空间复杂度O(1). 思路: 关键词:一次,两次. 出现两次会带来什么效果?联想到异或,一个数与 ...

  2. 找出数组中只出现过一次的数

    一个大数组,在1到25000之间,只有4K memory, 打印出其中正好只出现过一次的数.没出现过,出现过2次,3次,或更多,都不打印. solutions: 1)位图法,但每个数有3个状态:0,1 ...

  3. 找出数组中只出现1次的两个元素

    通过位运算可以得到只出现1次的唯一元素,但是如果有两个元素出现1次,则需要更进一步. 对整个数组依次进行异或运算后,得到的是两个出现一次元素的异或,之后将这两个元素的最后面是1的位记录下来,并以此为标 ...

  4. 微策略2011校园招聘笔试题(找出数组中两个只出现一次的数字)

    1.8*8的棋盘上面放着64个不同价值的礼物,每个小的棋盘上面放置一个礼物(礼物的价值大于0),一个人初始位置在棋盘的左上角,每次他只能向下或向右移动一步,并拿走对应棋盘上的礼物,结束位置在棋盘的右下 ...

  5. 找出数组中出现次数超过一半的数

    算法--找出数组中出现次数超过一半的数      每当我看到经典的算法题,就怀念高中,感觉很多算法题就是高中的题目,谁叫哥只读了个专科,高数基本相当没学.      有空要看看高数啊,想当年数学那是相 ...

  6. [LeetCode] Find All Numbers Disappeared in an Array 找出数组中所有消失的数字

    Given an array of integers where 1 ≤ a[i] ≤ n (n = size of array), some elements appear twice and ot ...

  7. 找出数组中最大值次大值的一次遍历方法(C++)

    写在前面 昨天做了一道LeetCode题(747. 至少是其他数字两倍的最大数 - 力扣(LeetCode) (leetcode-cn.com)), 大致意思是找出数组中的最大值和次大值并返回最大值索 ...

  8. java 数组不重复_java如何找出数组中的不重复数字

    找出数组中不重复的一个数字,题目大致是这样的:int[] a = { 1, 2, 3, 4, 3, 2, 1 }; 在线视频教程推荐:java在线学习 解决办法是:public static int ...

  9. 给定一个含n(n≥1)个整数的数组,请设计一个在时间上尽可能高效的算法,找出数组中未出现的最小正整数。

    笔者初涉<算法设计与分析>这门专业课,在做一些算法设计题的过程中遇到一些小感悟,特此记录和大家分享. 下面直接给出算法题目: 给定一个含n(n≥1)个整数的数组,请设计一个在时间上尽可能高 ...

最新文章

  1. js的作用域链,原型链,以及闭包函数理解
  2. 一、学爬虫前,你需要知道的爬虫常识
  3. python学习笔记(二)列表(List)操作方法详解
  4. ASP.NET页面间数据传递的几种方法
  5. Vue中使用节流Lodash throttle
  6. (转)Windows Form Application 读取并修改App.config文件
  7. Cisco ASA防火墙基础--转载http://wenzhongxiang.blog.51cto.com/6370734/1249746
  8. 软件天才都是训练出来的
  9. ERROR 1010 (HY000): Error dropping database (can't rmdir './myapp', errno: 39)
  10. 《逐梦旅程:Windows游戏编程之从零开始》
  11. C语言中数据的输出格式有哪些?
  12. 学会这4个Excel实用技巧,数据分析立马高人一等
  13. 2023年浙大MEM英语二作文干货模版:临阵磨枪可用
  14. 【职场攻略】送礼给老板有讲究
  15. android 多个按键精灵,给大家分享一个,按键精灵安卓版,找多图, 以及找多图返回多个坐标的,相信大家绝对用得到 _ 按键精灵手机版 - 按键精灵论坛...
  16. dw自定义html模板,用DW编辑网站模板的方法
  17. 音视频开发:大华摄像头配置RTSP与RTMP地址访问视频画面
  18. 北京铁路二中2021高考成绩查询,2021北京高考成绩查询入口
  19. 101页下载 机器学习、深度学习绘图模板.ppt
  20. Error: could not open `C:\Java\jre7\lib\amd64\jvm.cfg';JAVA_HOME环境变量失效的解决办法

热门文章

  1. mysql空值判断怎么优化_MySQL查询语句优化的十个小技巧!
  2. html+js按钮隐藏/显示
  3. 10亿台移动设备数据告诉你:移动互联网已是年轻人天下
  4. https双向认证訪问管理后台,採用USBKEY进行系统訪问的身份鉴别,KEY的证书长度大于128位,使用USBKEY登录...
  5. Android Studio 添加图标
  6. [sig12]几个AAA游戏中的阴影技术
  7. 24 个 Docker 常见问题处理技巧
  8. 呼叫系统呼叫中心crm系统
  9. 离散数学学习笔记 第一章 集合
  10. 电影放映机0.8K服务器维修流程,电影放映机的工作原理