《剑指offer》算法题第九天
今日题目:
- 整数中1出现的次数
- 把数组排成最小的数
- 丑数
- 第一个只出现一次的字符位置
今天的题目相对比较难,特别是第1题和第3题很考验数学功底,下面我们一题一题来看看。
1.整数中1出现的次数
题目描述:
输入一个整数n,求1~n这n个整数的十进制表示中1出现的次数。例如,输入12,1~12这些整数中包含1的数字有1,10,11,和12,1一共出现了5次。 思路:
这道题分别有递归和迭代两种解法,第一次看见这个题目比较难想到,可参考:
递归:http://blog.csdn.net/gatieme/article/details/51292339
代码如下:
//递归
public class Solution {
public int NumberOf1Between1AndN_Solution(int n) {
if(n == 0) return 0;
else if(n > 0 && n < 10) return 1;
else{
int high = n;
int weight = 1;
while(high >= 10){
high /= 10;
weight *= 10;
} if(high == 1){
return NumberOf1Between1AndN_Solution(weight-1)+
NumberOf1Between1AndN_Solution(n-weight)+
(n - weight + 1);
}else{
return high*NumberOf1Between1AndN_Solution(weight-1)+
NumberOf1Between1AndN_Solution(n - high*weight)+
weight;
} }
}
} //迭代
public class Solution {
int NumberOf1Between1AndN_Solution(int n){
int ones = 0;
for (int m = 1; m <= n; m *= 10) {
int a = n/m, b = n%m;
if(a%10 == 0)
ones += a / 10 * m;
else if(a%10 == 1)
ones += (a/10*m) + (b+1);
else
ones += (a/10+1)* m;
}
return ones;
}
}
2.把数组排成最小的数
题目描述:
输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个。例如输入数组{3,32,321},则打印出这三个数字能排成的最小数字为321323。 思路:
重新定义一种比较方法,然后对数组进行排序,最后再输出,博主这边是维护了一个最小堆。
代码如下:
public class Solution {
public String PrintMinNumber(int [] numbers) {
PriorityQueue<String> minHeap = new PriorityQueue(new Comparator<String>(){
public int compare(String str1,String str2){
String str_12 = str1+str2;
String str_21 = str2+str1;
return str_12.compareTo(str_21);
}
});
for(int n:numbers){
minHeap.add(""+n);
}
StringBuffer sb = new StringBuffer();
while(!minHeap.isEmpty()){
sb.append(minHeap.poll());
}
return sb.toString();
}
}
3. 丑数
题目描述:
把只包含因子2、3和5的数称作丑数(Ugly Number)。例如6、8都是丑数,但14不是,因为它包含因子7。 习惯上我们把1当做是第一个丑数。求按从小到大的顺序的第N个丑数。 思路:
由丑数的定义,每个丑数都是可以由比他小的丑数乘以2,3,或者5得到的,所以这边维护了一个数组和三个分别指向下一步将乘以2,3,或者5的数的指针,这样方便来求解下一个丑数,减小时间复杂度。
代码如下:
public class Solution {
public int GetUglyNumber_Solution(int index) {
if(index <= 0) return 0;
int[] ugly_nums = new int[index];
ugly_nums[0] = 1;
int next = 1;
int p2 = 0,p3 = 0,p5 = 0;
while(next < index){
//找到下一个丑数
int min = Min(ugly_nums[p2]*2,
ugly_nums[p3]*3,ugly_nums[p5]*5);
ugly_nums[next] = min;
//移动指针,将它们指向下一个该乘的数
while(ugly_nums[p2]*2 <= ugly_nums[next])
p2++;
while(ugly_nums[p3]*3 <= ugly_nums[next])
p3++;
while(ugly_nums[p5]*5 <= ugly_nums[next])
p5++;
next++;
}
return ugly_nums[next-1];
}
public int Min(int num1,int num2,int num3){
int min = (num1 > num2)?num2:num1;
return min<num3?min:num3;
}
}
4.第一个只出现一次的字符位置
题目描述:
在一个字符串(1<=字符串长度<=10000,全部由字母组成)中找到第一个只出现一次的字符,并返回它的位置。 思路:
比较简单,维护一个hashmap,将字符和出现的次数放入表中。
代码如下:
import java.util.*;
public class Solution {
public int FirstNotRepeatingChar(String str) {
if(str.length() <= 0) return -1;
HashMap<Character,Integer> map = new HashMap();
for(int i = 0; i < str.length(); i++){
char c = str.charAt(i);
if(!map.containsKey(c)){
map.put(c,1);
}else{
int val = map.get(c);
map.put(c,val+1);
}
}
for(int i = 0; i < str.length(); i++){
if(map.get(str.charAt(i)) == 1)
return i;
}
return -1; }
}
《剑指offer》算法题第九天的更多相关文章
- 剑指offer算法题
数组中只出现一次的数字(一个整型数组里除了两个数字之外,其他的数字都出现了两次.请写程序找出这两个只出现一次的数字): 解法在于位运算中的异或,直接异或可以得到这两个数的异或,按照最后的有效数字位可以 ...
- 剑指offer算法总结
剑指offer算法学习总结 节选剑指offer比较经典和巧妙的一些题目,以便复习使用.一部分题目给出了完整代码,一部分题目比较简单直接给出思路.但是不保证我说的思路都是正确的,个人对算法也不是特别在行 ...
- 剑指Offer——算法复杂度中的O(logN)底数是多少
剑指Offer--算法复杂度中的O(logN)底数是多少 前言 无论是计算机算法概论.还是数据结构书中,关于算法的时间复杂度很多都用包含O(logN)这样的描述,但是却没有明确说logN的底数究竟是多 ...
- 剑指 offer 第一题: 二维数组中的查找
打算写 图解剑指 offer 66 题 的系列文章,不知道大家有没有兴趣
- 剑指Offer编程题2——替换空格
剑指Offer编程题2——替换空格 题目描述 请实现一个函数,将一个字符串中的每个空格替换成“%20”.例如,当字符串为We Are Happy.则经过替换之后的字符串为We%20Are%20Happ ...
- 剑指Offer编程题1——二维数组中的查找
剑指Offer编程题1---------------二维数组中的查找 题目描述 在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完 ...
- 剑指offer编程题66道题 36-66
36.两个链表的第一个公共节点 题目描述 输入两个链表,找出它们的第一个公共结点. 1.具有重合节点的两个链表是一个Y字性,用两个堆栈放这两个链表,从尾部开始遍历,直到遍历到最后一个重合节点. 这种算 ...
- 牛客网剑指offer刷题总结
二维数组中的查找: 题目描述:在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数. 两 ...
- LeetCode剑指Offer刷题总结(一)
LeetCode过程中值得反思的细节 以下题号均指LeetCode剑指offer题库中的题号 本文章将每周定期更新,当内容达到10题左右时将会开下一节. 二维数组越界问题04 public stati ...
- 剑指offer编程题Java实现——面试题11数值的整数次方
题目: 实现函数double power(double base,int exponent),求base的exponent次方.不得使用库函数,同时不需要考虑大数问题. 解题思路:最一般的方法实现数值 ...
随机推荐
- 【重启C++】-- 序
好久没看C++的东西了,该忘的也忘得差不多了,现在又要开始学,一点一滴的记录起来吧.
- 本地代码库,提交远程git
1.在git上新建项目,并填好相关信息 2.新建成功后,复制项目地址 3.idea新建本地仓库 4.Add所有文件,然后提交(commit) 5.先打开push界面,设置git远程地址,然后关掉,先p ...
- Springboot导出Excel并下载
引入相关依赖 <!--数据导出excel--> <!-- https://mvnrepository.com/artifact/org.apache.poi/poi --> & ...
- 另类--kafka集群中jmx端口设置
# 监控kafka集群 # 有一个问题,需要在kafka-server-start.sh文件中配置端口,有如下三种办法 # 第一种:复制并修改kafka目录,比如kafka-1,kafka-2,kaf ...
- 【原创】运维基础之Amplify
官方:https://www.nginx.com/products/nginx-amplify/ NGINX Amplify is a SaaS‑based monitoring tool for t ...
- centos安装配置mariadb
CentOS7下使用yum安装MariaDB CentOS 6 或早期的版本中提供的是 MySQL 的服务器/客户端安装包,但 CentOS 7 已使用了 MariaDB 替代了默认的 MySQL.M ...
- 移动端iOS点击闪烁
移动端iOS点击闪烁 1. $("#id").bind("touchstart click",function(e){ 2. e.stopPropagation ...
- element-ui 表格可编辑添加删除
<template> <div id="Cold_all"> <div class="Cold_Left"> <el- ...
- 链接进入react二级路由,引发的子组件二次挂载
这个问题很怪,我两个二级路由从链接进入的时候,会挂载两次子组件. 从链接进入,是因为新页面在新标签页打开的. 有子组件是因为公共组件提取 同样的操作,有一些简单的二级路由页面,就不会挂载两次. 讲道理 ...
- 超简单!教你如何修改源列表(sources.list)来提高软件访问速度
因为Ubuntu官方的源地址不在国内,所以在国内的访问速度非常慢,比如:我们要下载或是更新软件那速度比蜗牛还慢.所以,我们需要改成国内的镜像服务器,这样,我们在下载或更新软件的时候就会很快了. 配置步 ...