剑指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的范围内. 数组中某些数字是重复的,但不知道有几个数字是重复的.也不知道每个数字重复几次.请找出数组中任意一个重复的数字. 例如,如果输入长度为 ...
随机推荐
- Java+eclipse技巧小总结
首先是打开Content Assistant,自动代码补全 Window -> Preferences -> Java -> Editor -> Content Assist, ...
- who are you?
不多说,直接使用脚本跑 # -*- coding:utf-8 -*- import requests import string url = "http://ctf5.shiyanbar.c ...
- Button事件的三种实现方法
onclick事件的定义方法,分为三种,分别为在xml中进行指定方法:在Actitivy中new出一个OnClickListenner():实现OnClickListener接口三种方式. 1.在xm ...
- .Net微信网页开发之使用微信JS-SDK自定义微信分享内容
第一步.微信JS-SDK的使用步骤,配置信息的生成获取讲解: 关于JS-SDK的使用步骤和timestamp(时间戳),nonceStr(随机串),signature(签名),access_token ...
- 【译】宣告推出.NET Core 3.0 Preview 7(英雄的黎明)
今天,我们宣布推出.NET Core 3.0 Preview 7.我们已经从创建新特性阶段过渡到了完善版本阶段.对于其余的预览版,我们将把重点放在质量(改进)上. 在Windows,macOS和Lin ...
- nginx(二)
nginx rewrite Nginx提供的全局变量或自己设置的变量,结合正则表达式和标志位实现url重写以及重定向.rewrite只能放在server{},location{},if{}中,并且 ...
- Linux系统安装jdk——rpm版
这里简单地阐述一下rpm.deb.tar.gz的区别. rpm格式的软件包适用于基于Red Hat发行版的系统,如Red Hat Linux.SUSE.Fedora. deb格式的软件包则是适用于基于 ...
- [转]PHP的类自动加载机制,spl_autoload_register使用介绍
转自 http://blog.csdn.net/hguisu/article/details/7463333: 在PHP开发过程中,如果希望从外部引入一个class,通常会使用include和requ ...
- 第二章 jQuery框架使用准备
window常用属性: History:有关客户访问过的URL的信息 Location: 有关当前url的信息 常用方法: Confirm()将弹出一个确认对话框 open()在页面上弹出一个新的浏览 ...
- 思路重要or技术重要?
1,思路串通代码的重要性 前段时间,同事在工作上出现一点难题,在技术大佬中看起来算是微不足道的一点小事,由于没有思路,代码也无从下手,他在百度上条框上搜索自己想要的答案,却始终没有比较理想的,大部分的 ...