剑指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的范围内. 数组中某些数字是重复的,但不知道有几个数字是重复的.也不知道每个数字重复几次.请找出数组中任意一个重复的数字. 例如,如果输入长度为 ...
随机推荐
- 【基本数据结构-集合(set)详解】-C++
集合是数学中的一个基本概念,通俗地理解,集合是由一些不重复的数据组成的.比如 就是{1,2,3} 一个有1,2,3三个元素的集合. 在 C++ 中我们常用的集合是 set . 它包含在头文件#incl ...
- py+appium微信公众号自动化(已搞定多个坑)
最近需要做微信公众号的自动化测试,遇到了不少坑. 微信公众号自动化与app自动化还是有区别的,因为多了不少坑.打开微信x5内核调试的就不说了,百度有. 1.首先,微信公众号有webview,uiaut ...
- 最好的导航分割栏,分割线,实现底部透明,纯css
<div class="Ui_Ct_Line padding_5"> <div>为您推荐</div> </div> .Ui_Ct_L ...
- python 之 并发编程(守护进程、互斥锁、IPC通信机制)
9.5 守护进程 主进程创建守护进程 其一:守护进程会在主进程代码执行结束后就立即终止 其二:守护进程内无法再开启子进程,否则抛出异常:AssertionError: daemonic process ...
- jmeter_遍历转换浮点时间戳
概述 近期帮朋友解决了一个浮点时间戳转换的问题,在这里记录一下. 具体场景是有一个十位浮点时间戳的list,需要遍历转换为当前的标准时间. list如下: 实现步骤 实现步骤其实很简单,只需要一个fo ...
- c++小游戏——杀手
杀手小游戏 会有一个存活者:(1 2 3 4 5),如果出现(1 0 3 4 5),代表二号已经死了. 一号有3次复活权 且有一次随机诅咒权(即当自己被杀死时,会随机诅咒另外一个人,当然不是死人或自己 ...
- [leetcode] 72. Edit Distance (hard)
原题 dp 利用二维数组dp[i][j]存储状态: 从字符串A的0~i位子字符串 到 字符串B的0~j位子字符串,最少需要几步.(每一次删增改都算1步) 所以可得边界状态dp[i][0]=i,dp[0 ...
- Unity AR Foundation 和 CoreML: 实现手部的检测和追踪
0x00 前言 Unity的AR Foundation通过上层抽象,对ARKit和ARCore这些底层接口进行了封装,从而实现了AR项目的跨平台开发能力. 而苹果的CoreML是一个可以用来将机器学习 ...
- C#汽车租赁系统 完整版
Truck.cs类 //卡车类 public class Truck : Vehicle1 { //重载 public int Load { get; set; } //构造函数 public T ...
- 文件A的内容复制到B
1.脚本 from sys import argvfrom os.path import existsscript,from_file,to_file = argvprint("Copy f ...