2022-3-20 剑指offer day37
题1:
JZ43 整数中1出现的次数(从1到n整数中1出现的次数)
描述
输入一个整数 n ,求 1~n 这 n 个整数的十进制表示中 1 出现的次数
例如, 1~13 中包含 1 的数字有 1 、 10 、 11 、 12 、 13 因此共出现 6 次
例如, 1~13 中包含 1 的数字有 1 、 10 、 11 、 12 、 13 因此共出现 6 次
注意:11 这种情况算两次
数据范围: 1 \le n \le 30000 \1≤n≤30000
进阶:空间复杂度 O(1) \O(1) ,时间复杂度 O(lognn) \O(lognn)
1 public class Solution { 2 public int NumberOf1Between1AndN_Solution(int n) { 3 // 从个位数开始 4 int base = 1; 5 // 总的出现1的次数现在为 0 6 int res = 0; 7 // 不能超过n 8 while(base <= n){ 9 // 求出当前位 ,高位,低位 10 int cur = n/base%10; 11 int a = n/base/10; 12 int b = n%base; 13 14 // 分三类情况讨论,对应上面解释的三种情况 15 if(cur > 1) 16 res += (a+1)*base; 17 else if(cur == 0) 18 res += a*base; 19 else res += a*base+b+1; 20 base *= 10; // 位数向前移一位 21 } 22 return res; // 最后得到全部出现1的次数,返回 23 } 24 }
思路:考虑每一位的情况,再累加/。
题2:
JZ45 把数组排成最小的数
描述
输入一个非负整数数组numbers,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个。
例如输入数组[3,32,321],则打印出这三个数字能排成的最小数字为321323。
1.输出结果可能非常大,所以你需要返回一个字符串而不是整数
2.拼接起来的数字可能会有前导 0,最后结果不需要去掉前导 0
2.拼接起来的数字可能会有前导 0,最后结果不需要去掉前导 0
数据范围:
0<=len(numbers)<=100
1 import java.util.*; 2 3 public class Solution { 4 public String PrintMinNumber(int [] numbers) { 5 PriorityQueue<Integer> queue=new PriorityQueue<>(new Comparator<Integer>(){ 6 @Override 7 public int compare(Integer a,Integer b){ 8 int l1=0,l2=0; 9 int t1=a,t2=b; 10 while (a>0) { 11 a/=10; 12 l1++; 13 } 14 while (b>0){ 15 b/=10; 16 l2++; 17 } 18 if (t1*Math.pow(10,l2)+t2>t2*Math.pow(10,l1)+t1) return 1; 19 else return -1; 20 } 21 }); 22 for (int x:numbers) queue.offer(x); 23 StringBuilder sb=new StringBuilder(); 24 while (!queue.isEmpty()) sb.append(queue.poll()); 25 return sb.toString(); 26 } 27 28 }
思路:优先队列排序,再拼接。
浙公网安备 33010602011771号