位运算

出现一次的数字和出现k次的数字

题目:出现k次和出现1次
描述:数组中只有一个数出现了1次,其他的数都出现了k次,请输出只出现1次的数。

第一次看到这道题,思考了一会,觉得可以使用Map集合来做,实在想不到怎么用位运算来解决,后来同学说可以使用"不进位加法"来做,这也是用"位运算"解题的核心,因此,在此记录一下两种解法。

1、解法1(位运算)

在上面,我们提到了"不进位加法",在解题之前,我们先补充一个知识。

如果2个相同二进制数做不进位的加法,如10+10,其结果为多少呢?很显然是:0。

那如果是10个相同十进制的数做不进位加法呢?如10个2,显然还是0。

因此我们可以得出一个小结论:k个相同的k进制数做不进位加法,其结果为0。

解法1:将所有数转为k进制,然后进行不进位的加法,最后,其结果只剩出现1次的数,再转为十进制输出即可。1、转为k进制1.1、如何转?Java中有封装好的Integer.toString(int i, int radix)2、不进位加法2.1、将转化的k进制数的每一位存放至二维数组中2.2、遍历二维数组,将每一列做和的结果存放至另外一个整型数组中2.3、遍历整型数组,对每一个元素进行取模运算,以达到不进位加法的效果2.4、转化为十进制后进行累加,输出的值就为出现1次的数的值。

/*** 获取出现一次的数字* 解法1:位运算** @param nums 数组* @param k    几个相同的数* @return 若存在,则返回该数*/
public static int getOnceNumByBitOperate(int[] nums, int k) {//数组的长度int length = nums.length;//用二为数组来存放nums数组元素转化为k进制数的每一位char[][] kRadix = new char[length][];//转成k进制字符数组int maxLen = 0;for (int i = 0; i < length; i++) {/** Integer.toString(nums[i], k):转化为k进制数* .reverse():将k进制字符串反转,例如21则反转为12。* .toString():转化为字符串* .toCharArray():将字符串转化为字符数组*/kRadix[i] = new StringBuilder(Integer.toString(nums[i], k)).reverse().toString().toCharArray();if (kRadix[i].length > maxLen) {//记录最长的列,后面遍历会用到maxLen = kRadix[i].length;}}/** 此数组用于存放每一个比特位做完不进位的和* 实际上,这里就是做了普通的加法而已,后面会对这个和进行取余操作,等价于不进位加法的效果。*/int[] resArr = new int[maxLen];//不进位加法for (int i = 0; i < length; i++) {for (int j = 0; j < maxLen; j++) {/* 如果j大于等于二位数组某一行的长度时,则+0即可。* j >= kRadix[i].length 也可写为 (j+1) >= kRadix[i].length*/if (j >= kRadix[i].length) {resArr[j] += 0;} else {/** 为何要减去'0'?* 因为,resArr是int类型,而kRadix数组是字符类型* '0'的十进制ASCII码为48,若没有减去'0',则会存在48的误差,比如2-0 = 0,但是 2-'0' = 2-48 = -46*/resArr[j] += (kRadix[i][j] - '0');}}}int res = 0;//遍历数组,拿到每个位做完加法的结果for (int i = 0; i < maxLen; i++) {/* %k:取模运算,相当于完成不进位加法的效果* * (int) (Math.pow(k, i)):转化为十进制*/res += (resArr[i] % k) * (int) (Math.pow(k, i));}return res;
}

2、解法2(Map集合)

解法2:Map集合1、创建一个HashMap,键Key用来保存数组元素,值Value用来记录数组元素出现的次数2、遍历数组,判断Map的键是否存在2.1、存在,则获取其值value,加1后2.2、不存在,直接将值value设置为13、遍历Map,获取所有的键key,再通过键拿到其值value3.1、判断值value是否为1,若是则输出键key
/*** 获取出现一次的数字* 解法2:Map集合** @param nums 数组* @return 若存在,则返回该数;反之,返回-1*/public static int getOnceNum02(int[] nums) {Map<Integer, Integer> map = new HashMap<>(nums.length);//2、遍历数组for (int num : nums) {if (map.containsKey(num)) {//2.1、存在int value = map.get(num);map.put(num, ++value);} else {//2.2、不存在map.put(num, 1);}}//3、遍历MapSet<Integer> keySet = map.keySet();for (Integer key : keySet) {//存在,返回key,即出现一次的数if (map.get(key) == 1) {return key;}}//不存在返回-1return -1;}

注:解法1可能比解法2晦涩难懂,效率也差,但是我认为解法1的思想还是值得学习的。


调试结果:

public static void main(String[] args) {//假设出现了k次int[] nums = new int[]{3, 3, 3, 9, 6, 6, 6, 8, 8, 8, 10, 10, 10};System.out.println("(位运算)出现一次的数:" + getOnceNumByBitOperate(nums, 3));System.out.println("(Map集合)出现一次的数:" + getOnceNumByMap(nums));
}


如有错误,敬请指正!

算法题_位运算_9_出现一次的数字和出现k次的数字相关推荐

  1. 算法题_位运算_4_是不是2的整数次方

    位运算 是不是2的整数次方 如果已经吃透了上一道题<二进制数中"1"比特的个数>,只要稍加思考,就会发现这道题与上一道的考点是一样的,都是判断"1" ...

  2. HYSBZ(BZOJ) 4300 绝世好题(位运算,递推)

    HYSBZ(BZOJ) 4300 绝世好题(位运算,递推) Description 给定一个长度为n的数列ai,求ai的子序列bi的最长长度,满足bi&bi-1!=0(2<=i<= ...

  3. c语言用位运算将一个数清零,C语言学习笔记_位运算

    C语言学习笔记_位运算 知识点记录 基本位运算 按位与:全1为1,见0为0:与1相与无变化,与0相与变为0:可用于特定位清零 按位或:见1为1,全0为0:与1相或变为1,与0相或无变化:可用于特定位置 ...

  4. 算法之美 | 位运算的巧妙奥秘(一) | JAVA中位运算的深入浅出

    文章目录 前言 一.位运算符号 二.位运算的运算规则 扩展 前言 传智杯初赛后有感而写,我目前阶段所学习的算法,只是最基础的数学,对于数字和数学公式还是不敏感,在小卡与质数2那道题,解题的思路只有最基 ...

  5. 【算法技巧】位运算装逼指南

    位算法的效率有多快我就不说,不信你可以去用 10 亿个数据模拟一下,今天给大家讲一讲位运算的一些经典例子.不过,最重要的不是看懂了这些例子就好,而是要在以后多去运用位运算这些技巧,当然,采用位运算,也 ...

  6. java的简单算法题_[2]十道算法题【Java实现】

    前言 清明不小心就拖了两天没更了-- 这是十道算法题的第二篇了-上一篇回顾:十道简单算法题 最近在回顾以前使用C写过的数据结构和算法的东西,发现自己的算法和数据结构是真的薄弱,现在用Java改写一下, ...

  7. LeetCode刷题:位运算(找不同 和 只出现一次的数字)

    1.常见的位运算 按位与&:(1&1=1,1&0=0,0&1=0,0&0=0); 按位或 | : (1 | 1=1,1 | 0=1,0 | 1=1,0 | 0= ...

  8. 疯子的算法总结(一) 位运算(快速幂、快速乘)

    一.预备知识(补码,反码) 计算机通过二进制表示整形数,比如int型32位有符号整形数: 1表示为:0000-00001(共32位) -1表示为:1111-1111(共32位) 补码计算法定义:非负数 ...

  9. 【算法】 - 动态规划 + 位运算

    题目描述 思路1: 写一个返回2进制中1数量的函数countOne 遍历0到num,对每一个数使用countOne,并将结果保存到res中返回 var countBits = function (nu ...

最新文章

  1. Angular\Vue解决页面数据加载时出现{{message}}闪烁的情况
  2. 中国超导产业投资风险及应用前景调研报告2021版
  3. BZOJ 3237: [Ahoi2013]连通图
  4. 2018.09.16模拟总结
  5. 网页性能优化(初窥)
  6. 前端学习(1438):vue三种安装方式
  7. python 进程与线程(理论部分)
  8. 图像处理之积分图应用三(基于NCC快速相似度匹配算法)
  9. linux下dnw工具安装和使用
  10. TensorFlow 是一个用于人工智能的开源神器
  11. UIView - CAGradientLayer
  12. (转)根据两点经纬度计算距离
  13. 线切割常用专用编程软件下载
  14. mysql的执行计划_MySQL——执行计划
  15. Couldn't figure out the Java version of /root/.jenkins/jdk/bin/java bash: /root/.jenkins/jdk/bin/jav
  16. 【ARM】Linaro Security module
  17. GIT无法提交到码云。原因可能是所在提交位置不对
  18. linux卸载飞行模式驱动,解决:Ubuntu飞行模式 使用硬件开关关闭
  19. 火影忍者ol手游服务器注册上限怎么办,火影忍者ol手游进不去是怎么办 火影忍者ol手游上不去原因详解...
  20. MCAL PWM Module详解

热门文章

  1. password_hash/password_verify/(JAVA)
  2. xpad a note tool for ubuntu
  3. 人人都想买湖景房!湖景房优缺点你知道吗?
  4. Unity DOTS 一文开启ECS大门
  5. 2022强大的修复版趣味心理测试小程序源码,趣味测试引流裂变神器,流量主激励广告实现管道收益
  6. [量化-025]某投资者的投资策略统计整理
  7. 掩码认证消息(MAM)详细介绍
  8. pytorch实现特征图可视化,代码简洁,包教包会
  9. 【DASH】低延迟流式传输和新算法
  10. 压在心底慢慢体会__珍藏的句子