zoukankan      html  css  js  c++  java
  • 《剑指offer》算法题第九天

    今日题目:

    1. 整数中1出现的次数
    2. 把数组排成最小的数
    3. 丑数
    4. 第一个只出现一次的字符位置

    今天的题目相对比较难,特别是第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

    代码如下:

     1 //递归
     2 public class Solution {
     3     public int NumberOf1Between1AndN_Solution(int n) {
     4         if(n == 0) return 0;
     5         else if(n > 0 && n < 10) return 1;
     6         else{
     7             int high = n;
     8             int weight = 1;
     9             while(high >= 10){
    10                 high /= 10;
    11                 weight *= 10;
    12             }
    13              
    14             if(high == 1){
    15                 return NumberOf1Between1AndN_Solution(weight-1)+
    16                     NumberOf1Between1AndN_Solution(n-weight)+
    17                     (n - weight + 1);
    18             }else{
    19                 return high*NumberOf1Between1AndN_Solution(weight-1)+
    20                     NumberOf1Between1AndN_Solution(n - high*weight)+
    21                     weight;
    22             }
    23              
    24         }
    25     }
    26 }
    27 
    28 
    29 //迭代
    30 public class Solution {
    31     int NumberOf1Between1AndN_Solution(int n){
    32         int ones = 0;
    33         for (int m = 1; m <= n; m *= 10) {
    34             int a = n/m, b = n%m;
    35             if(a%10 == 0)
    36                 ones += a / 10 * m;
    37             else if(a%10 == 1) 
    38                 ones += (a/10*m) + (b+1);
    39             else
    40                 ones += (a/10+1)* m;
    41         }
    42         return ones;
    43     }
    44 }

    2.把数组排成最小的数

    题目描述:
    输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个。例如输入数组{3,32,321},则打印出这三个数字能排成的最小数字为321323。

    思路:
    重新定义一种比较方法,然后对数组进行排序,最后再输出,博主这边是维护了一个最小堆。

    代码如下:

     1 public class Solution {
     2     public String PrintMinNumber(int [] numbers) {
     3         PriorityQueue<String> minHeap = new PriorityQueue(new Comparator<String>(){
     4             public int compare(String str1,String str2){
     5                 String str_12 = str1+str2;
     6                 String str_21 = str2+str1;
     7                 return str_12.compareTo(str_21);
     8             }
     9         });
    10         for(int n:numbers){
    11             minHeap.add(""+n);
    12         }
    13         StringBuffer sb = new StringBuffer();
    14         while(!minHeap.isEmpty()){
    15             sb.append(minHeap.poll());
    16         }
    17         return sb.toString();
    18     }
    19 }

    3. 丑数

    题目描述:
    把只包含因子2、3和5的数称作丑数(Ugly Number)。例如6、8都是丑数,但14不是,因为它包含因子7。 习惯上我们把1当做是第一个丑数。求按从小到大的顺序的第N个丑数。

    思路:
    由丑数的定义,每个丑数都是可以由比他小的丑数乘以2,3,或者5得到的,所以这边维护了一个数组和三个分别指向下一步将乘以2,3,或者5的数的指针,这样方便来求解下一个丑数,减小时间复杂度。

    代码如下:

     1 public class Solution {
     2     public int GetUglyNumber_Solution(int index) {
     3         if(index <= 0) return 0;
     4         int[] ugly_nums = new int[index];
     5         ugly_nums[0] = 1;
     6         int next = 1;
     7         
     8         int p2 = 0,p3 = 0,p5 = 0;
     9         while(next < index){
    10             //找到下一个丑数
    11             int min = Min(ugly_nums[p2]*2,
    12                          ugly_nums[p3]*3,ugly_nums[p5]*5);
    13             ugly_nums[next] = min;
    14             //移动指针,将它们指向下一个该乘的数
    15             while(ugly_nums[p2]*2 <= ugly_nums[next])
    16                 p2++;
    17             while(ugly_nums[p3]*3 <= ugly_nums[next])
    18                 p3++;
    19             while(ugly_nums[p5]*5 <= ugly_nums[next])
    20                 p5++;
    21             
    22             next++;
    23         }
    24         return ugly_nums[next-1];
    25     }
    26     
    27     public int Min(int num1,int num2,int num3){
    28         int min = (num1 > num2)?num2:num1;
    29         return min<num3?min:num3;
    30     }
    31 }

    4.第一个只出现一次的字符位置

    题目描述:
    在一个字符串(1<=字符串长度<=10000,全部由字母组成)中找到第一个只出现一次的字符,并返回它的位置。

    思路:
    比较简单,维护一个hashmap,将字符和出现的次数放入表中。

    代码如下:

     1 import java.util.*;
     2 public class Solution {
     3     public int FirstNotRepeatingChar(String str) {
     4         if(str.length() <= 0) return -1;
     5         HashMap<Character,Integer> map = new HashMap();
     6         for(int i = 0; i < str.length(); i++){
     7             char c = str.charAt(i);
     8             if(!map.containsKey(c)){
     9                 map.put(c,1);
    10             }else{
    11                 int val = map.get(c);
    12                 map.put(c,val+1);
    13             }
    14         }
    15         for(int i = 0; i < str.length(); i++){
    16             if(map.get(str.charAt(i)) == 1)
    17                 return i;
    18         }
    19         return -1;
    20         
    21     }
    22 }
  • 相关阅读:
    Volley的post使用
    android中asynctask的使用实例
    android中HttpClient的应用(POST方法)
    gson在android中的应用
    7、Web应用程序中的安全向量 -- 使用Retail部署配置
    6、Web应用程序中的安全向量 -- customErrors(适当的错误报告和堆栈跟踪)
    5、Web应用程序中的安全向量 -- Open Redirect Attack(开放重定向)
    4、Web应用程序中的安全向量 -- over-posting(重复提交)
    3、Web应用程序中的安全向量 -- cookie盗窃
    2、Web应用程序中的安全向量 -- CSRF/XSRF(跨站请求伪造)
  • 原文地址:https://www.cnblogs.com/wezheng/p/8418146.html
Copyright © 2011-2022 走看看