剑指offer总结一:字符、数字重复问题
问题1:字符串中第一个不重复的字符
题目描述
请实现一个函数用来找出字符流中第一个只出现一次的字符。例如,当从字符流中只读出前两个字符"go"时,第一个只出现一次的字符是"g"。当从该字符流中读出前六个字符“google"时,第一个只出现一次的字符是"l"。
输出描述:
如果当前字符流没有存在出现一次的字符,返回#字符。
解题思路:遍历字符串,用map保存每个字符出现的次数,map的key-value分别是字符-字符出现的次数count,输出第一个count为1的字符。但是最先想到的hashmap是无序的,遍历是不能保证第一个找到的满足条件的字符就是字符串中第一个出现的不重复的字符,因此需要改用LinkedHashMap.因为LinkedHashMap是有序的,可以按照输入顺序遍历。
代码
import java.util.LinkedHashMap;
import java.util.LinkedList;
public class Solution {
LinkedHashMap<Character, Integer> map = new LinkedHashMap<>();
LinkedList<Character> input = new LinkedList<>();
//Insert one char from stringstream
public void Insert(char ch)
{
if(map.containsKey(ch)){
map.put(ch,map.get(ch)+1);
}else{
map.put(ch,1);
}
input.add(ch);
}
//return the first appearence once char in current stringstream
public char FirstAppearingOnce()
{
for(char c:input){
if(map.get(c)==1){
return c;
}
}
return '#';
}
}
问题2:数组中重复的数字
在一个长度为n的数组里的所有数字都在0到n-1的范围内。 数组中某些数字是重复的,但不知道有几个数字是重复的。也不知道每个数字重复几次。请找出数组中任意一个重复的数字。 例如,如果输入长度为7的数组{2,3,1,0,2,5,3},那么对应的输出是第一个重复的数字2。
解题思路:
常规解法:和问题1类似用map保存出现的次数,然后在遍历map
优化解法:因为数组中数字有一个特点:都在[0,n-1]范围内,利用这个特点。遍历数组,将numbers[i]对于的下标处的值加上一个n,这样遍历到大于n的值时就说明这个值所在的下标数已经出现过,则找出了重复数字——下标值。
代码
public boolean duplicate(int numbers[],int length,int [] duplication) {
for(int i=0;i<length;i++){
int index = numbers[i]>=length?numbers[i]-length:numbers[i];
if(numbers[index]>=length){
duplication[0] = index;
return true;
}else{
numbers[index]+=length;
}
}
return false;
}
问题3:数组中只出现一次的数字
题目描述一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。
解题思路:这道题突破点在于其他数字都出现了两次,重复次数确定是2,而只存在两个数字只出现一次。用异或运算,两个相同的数异或为0,任何一个数与0异或都是它本身,将所有数字都异或之后的结果其实就是那两个不重复的数字异或的结果,然后找出这个结果中第一个不为1的位index,按照第index位是否为0,可以将数组分成两组,每一组中包含一个不重复的数字和其他重复两遍的数组,在两组内再异或就可得到两个不重复的数字
代码
//num1,num2分别为长度为1的数组。传出参数
//将num1[0],num2[0]设置为返回结果
public class Solution {
public void FindNumsAppearOnce(int [] array,int num1[] , int num2[]) {
int len = array.length;
if(len<2){
return ;
}
int bitResult = 0;
for(int i=0;i<array.length;i++){
bitResult ^= array[i];
}
int index = findFirst1(bitResult);
num1[0] = num2[0] = 0;
for(int i=0;i<len;i++){
if(isBit1(array[i],index)){
num1[0] ^= array[i];
}else{
num2[0] ^= array[i];
}
}
}
private int findFirst1(int num){
int index = 0;
while((num&1)==0){
num>>=1;
index++;
}
return index;
}
private boolean isBit1(int num,int index){
return (num>>index&1)==1;
}
}
问题4:数组中出现次数超过一半的数字
题目描述:数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。如果不存在则输出0。
解题思路
解法1:排序,若存在满足条件的数则它一定在中间位置
解法2:摩尔投票法,若满足条件的数存在,将其看做是1,其他数看作是-1
代码(解法2)
public class Solution {
public int MoreThanHalfNum_Solution(int [] array) {
int candicate=0;
int count = 0;
for(int i=0;i<array.length;i++){
if(count==0){
candicate = array[i];
}
count+=candicate==array[i]?1:-1;
}
//verfying
count=0;
for(int i=0;i<array.length;i++){
if(array[i]==candicate){
count++;
}
}
return count>array.length/2?candicate:0;
}
}
总结
对于求解重复字符或重复数字问题,基本思路用hashmap(linkedhashmap)解决。
对于题目中给定的特定环境一般会有一些优化解法。关键点就是抓住题目中的特性。
剑指offer总结一:字符、数字重复问题的更多相关文章
- 剑指Offer - 九度1349 - 数字在排序数组中出现的次数
剑指Offer - 九度1349 - 数字在排序数组中出现的次数2013-11-23 00:47 题目描述: 统计一个数字在排序数组中出现的次数. 输入: 每个测试案例包括两行: 第一行有1个整数n, ...
- 【剑指Offer】删除链表中重复的结点 解题报告(Python)
[剑指Offer]删除链表中重复的结点 解题报告(Python) 标签(空格分隔): 剑指Offer 题目地址:https://www.nowcoder.com/ta/coding-interview ...
- Go语言实现:【剑指offer】删除链表中重复的结点
该题目来源于牛客网<剑指offer>专题. 给定一个排序链表,删除所有含有重复数字的节点,只保留原始链表中没有重复出现的数字. 示例 1: 输入: 1->2->3->3- ...
- 【剑指offer】03.数组中重复的数组
剑指 Offer 03. 数组中重复的数字 知识点:数组:哈希表:萝卜占坑思想 题目描述 找出数组中重复的数字. 在一个长度为 n 的数组 nums 里的所有数字都在 0-n-1 的范围内.数组中某些 ...
- 【剑指offer】删除字符也出现在一个字符串
转载请注明出处:http://blog.csdn.net/ns_code/article/details/27110873 剑指offer上的字符串相关题目. 题目:输入两个字符串,从第一字符串中删除 ...
- 【Java】 剑指offer(18) 删除链表中重复的结点
本文参考自<剑指offer>一书,代码采用Java语言. 更多:<剑指Offer>Java实现合集 题目 在一个排序的链表中,如何删除重复的结点?例如,在图3.4(a)中重 ...
- 【剑指offer】删除链表中重复的节点,C++实现(链表)
0.简介 本文是牛客网<剑指offer>笔记. 1.题目 在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针.例如,链表1-> ...
- 剑指offer系列24---数组中重复的数字
* [24] * [题目]在一个长度为n的数组里的所有数字都在0到n-1的范围内. * 数组中某些数字是重复的,但不知道有几个数字是重复的. * 也不知道每个数字重复几次. * 请找出数组中任意一个重 ...
- 《剑指offer》-找到数组中重复的数字
题目描述 在一个长度为n的数组里的所有数字都在0到n-1的范围内. 数组中某些数字是重复的,但不知道有几个数字是重复的.也不知道每个数字重复几次.请找出数组中任意一个重复的数字. 例如,如果输入长度为 ...
随机推荐
- 个人永久性免费-Excel催化剂功能第81波-指定单元格区域内容及公式填充
在日常数据处理过程中,需要对缺失数据进行填充时,按一定逻辑规则进行处理,实现快速填充,规范数据源.此篇给大家带来多种填充数据的场景. 业务使用场景 对各种系统中导出的数据,很多时候存在数据缺失的情况, ...
- c语言进阶13-线性表之顺序表
一. ACM算法:顺序表的查找 顺序表的查找指获取顺序表的第i个元素.对于线性表的顺序存储结构来说,如果我们要实现获取元素的操作(GetElem),即将线性表L中的第i个位置元素值返回.就程序而言,只 ...
- E-R图怎么绘制
E-R图中主要涉及到的元素有: 实体:用长方形表示 关联关系:用菱形表示 属性:用椭圆表示 参考一个例子:
- JAVA项目从运维部署到项目开发(五. Nginx)
<Nginx与Nginx-rtmp-module搭建RTMP视频直播和点播服务器>一文简单介绍了关于直播数据流的nginx相关配置,下面简单介绍下各种项目如何配置nginx. web项目. ...
- Javaweb入门 数据库第二天
接着说昨天语法中提到的drop,delete和truncate的区别 drop用于删除库和表,不能用于删除表记录 delete和truncate都可以用于删除表记录,不能用于删除库和表 而delete ...
- java连接oracle数据库jdbc
driver = oracle.jdbc.driver.OracleDriver url = jdbc:oracle:thin:@localhost:1521:orcl
- Win常用软件
本节只适合windows系统 VScode 下载 安装 双击安装 打开目录方式 右键文件夹->使用VSCode打开 命令行打开 code folder [dzlua@win10:~]$ ls a ...
- 【iOS】Updating local specs repositories
使用 Pods 时遇到这个问题,原因是被墙了……需换成下面命令: pod install --verbose --no-repo-update
- jboss 未授权访问漏洞复现
jboss 未授权访问漏洞复现 一.漏洞描述 未授权访问管理控制台,通过该漏洞,可以后台管理服务,可以通过脚本命令执行系统命令,如反弹shell,wget写webshell文件. 二.漏洞环境搭建及复 ...
- Confluence未授权模板注入/代码执行(CVE-2019-3396)
--- title: Confluence未授权模板注入/代码执行(CVE-2019-3396) tags: [poc,cve] num :g7y12 --- # 简介 --- Confluence是 ...