剑指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的范围内. 数组中某些数字是重复的,但不知道有几个数字是重复的.也不知道每个数字重复几次.请找出数组中任意一个重复的数字. 例如,如果输入长度为 ...
随机推荐
- ASP.NET Core MVC 之模型(Model)
1.模型绑定 ASP.NET Core MVC 中的模型绑定将数据从HTTP请求映射到操作方法参数.参数既可以是简单类型,也可以是复杂类型.MVC 通过抽象绑定解决了这个问题. 2.使用模型绑定 当 ...
- LaTeX大全
1.指数和下标可以用^和_后加相应字符来实现.比如: 2.平方根(square root)的输入命令为:\sqrt,n 次方根相应地为: \sqrt[n].方根符号的大小由LATEX自动加以调整.也可 ...
- python虚拟环境管理 Pipenv 使用说明
安装 pip install pipenv 检查是否安装成功 pipenv --version 创建虚拟环境(在工程文件夹下) pipenv install 默认下,Pipenv统一管理所有虚拟环境 ...
- RabbitMQ 实践之在处理异步任务中的流程
一.背景: 我司的系统,用户可以创建任务,启动任务,但任务的运行需要很长的时间,所以采用消息队列的方式,后台异步处理. 这里所用到的是 RabbitMQ . 二.MQ 处理任务的流程 ① ② ③ ④ ...
- PHP与ECMAScript_3_常用字符串函数
PHP ECMAScript 长度 strlen($str) str.length 查找类 $str[n] ...
- Ubuntu下Mongo的安装和笔记
在linux下的安装 打开https://www.mongodb.com/download-center#community选择linux然后选择自己的Version复制DOWNLOAD旁边的链接 打 ...
- eclipse Mac 下补全代码
1. 每次输入都自动提示 点击 Eclipse,使其成为第一响应者,preferences->Java->Editor->Content Assist再右下角 Auto activa ...
- Mysql架构简要
1. MySql 最上层是一些客户端和连接服务,包含本地sock通信和大多数基于客户端/服务端工具实现的类似于tcp/ip的通信. 主要完成一些类似于连接处理.授权认证.及相关的安全方案.在该层上引入 ...
- 释放你的硬盘空间!——Windows 磁盘清理技巧
引言 用了Windows系统的各位都知道,作为系统盘的C盘的空间总是一天比一天少.就拿本人的例子来说,自从安装了Win10,就发现,C盘从一开始的10几G占用,到现在慢慢变成了20G.30G….占用只 ...
- 跟着大彬读源码 - Redis 9 - 对象编码之 三种list
目录 1 ziplist 2 skiplist 3 quicklist 总结 Redis 底层使用了 ziplist.skiplist 和 quicklist 三种 list 结构来实现相关对象.顾名 ...