成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

數據結構與算法之單調遞增的數字

開發 前端 算法
本題只要想清楚個例,例如98,一旦出現strNum[i - 1] > strNum[i]的情況(非單調遞增),首先想讓strNum[i - 1]減一,strNum[i]賦值9,這樣這個整數就是89。就可以很自然想到對應的貪心解法了。

[[439817]]

單調遞增的數字

力扣題目鏈接:https://leetcode-cn.com/problems/monotone-increasing-digits

給定一個非負整數 N,找出小于或等于 N 的最大的整數,同時這個整數需要滿足其各個位數上的數字是單調遞增。

(當且僅當每個相鄰位數上的數字 x 和 y 滿足 x <= y 時,我們稱這個整數是單調遞增的。)

示例 1:

  • 輸入: N = 10
  • 輸出: 9

示例 2:

  • 輸入: N = 1234
  • 輸出: 1234

示例 3:

  • 輸入: N = 332
  • 輸出: 299

說明: N 是在 [0, 10^9] 范圍內的一個整數。

暴力解法

題意很簡單,那么首先想的就是暴力解法了,來我替大家暴力一波,結果自然是超時!

代碼如下:

  1. class Solution { 
  2. private: 
  3.     bool checkNum(int num) { 
  4.         int max = 10; 
  5.         while (num) { 
  6.             int t = num % 10; 
  7.             if (max >= t) max = t; 
  8.             else return false
  9.             num = num / 10; 
  10.         } 
  11.         return true
  12.     } 
  13. public
  14.     int monotoneIncreasingDigits(int N) { 
  15.         for (int i = N; i > 0; i--) { 
  16.             if (checkNum(i)) return i; 
  17.         } 
  18.         return 0; 
  19.     } 
  20. }; 
  • 時間復雜度:O(n * m) m為n的數字長度
  • 空間復雜度:O(1)

貪心算法

題目要求小于等于N的最大單調遞增的整數,那么拿一個兩位的數字來舉例。

例如:98,一旦出現strNum[i - 1] > strNum[i]的情況(非單調遞增),首先想讓strNum[i - 1]--,然后strNum[i]給為9,這樣這個整數就是89,即小于98的最大的單調遞增整數。

這一點如果想清楚了,這道題就好辦了。

局部最優:遇到strNum[i - 1] > strNum[i]的情況,讓strNum[i - 1]--,然后strNum[i]給為9,可以保證這兩位變成最大單調遞增整數。

全局最優:得到小于等于N的最大單調遞增的整數。

但這里局部最優推出全局最優,還需要其他條件,即遍歷順序,和標記從哪一位開始統一改成9。

此時是從前向后遍歷還是從后向前遍歷呢?

從前向后遍歷的話,遇到strNum[i - 1] > strNum[i]的情況,讓strNum[i - 1]減一,但此時如果strNum[i - 1]減一了,可能又小于strNum[i - 2]。

這么說有點抽象,舉個例子,數字:332,從前向后遍歷的話,那么就把變成了329,此時2又小于了第一位的3了,真正的結果應該是299。

所以從前后向遍歷會改變已經遍歷過的結果!

那么從后向前遍歷,就可以重復利用上次比較得出的結果了,從后向前遍歷332的數值變化為:332 -> 329 -> 299

確定了遍歷順序之后,那么此時局部最優就可以推出全局,找不出反例,試試貪心。

C++代碼如下:

  1. class Solution { 
  2. public
  3.     int monotoneIncreasingDigits(int N) { 
  4.         string strNum = to_string(N); 
  5.         // flag用來標記賦值9從哪里開始 
  6.         // 設置為這個默認值,為了防止第二個for循環在flag沒有被賦值的情況下執行 
  7.         int flag = strNum.size(); 
  8.         for (int i = strNum.size() - 1; i > 0; i--) { 
  9.             if (strNum[i - 1] > strNum[i] ) { 
  10.                 flag = i; 
  11.                 strNum[i - 1]--; 
  12.             } 
  13.         } 
  14.         for (int i = flag; i < strNum.size(); i++) { 
  15.             strNum[i] = '9'
  16.         } 
  17.         return stoi(strNum); 
  18.     } 
  19. }; 
  • 時間復雜度:O(n) n 為數字長度
  • 空間復雜度:O(n) 需要一個字符串,轉化為字符串操作更方便

總結

本題只要想清楚個例,例如98,一旦出現strNum[i - 1] > strNum[i]的情況(非單調遞增),首先想讓strNum[i - 1]減一,strNum[i]賦值9,這樣這個整數就是89。就可以很自然想到對應的貪心解法了。

想到了貪心,還要考慮遍歷順序,只有從后向前遍歷才能重復利用上次比較的結果。

最后代碼實現的時候,也需要一些技巧,例如用一個flag來標記從哪里開始賦值9。

其他語言版本

Java:

  1. 版本1 
  2. class Solution { 
  3.     public int monotoneIncreasingDigits(int N) { 
  4.         String[] strings = (N + "").split(""); 
  5.         int start = strings.length; 
  6.         for (int i = strings.length - 1; i > 0; i--) { 
  7.             if (Integer.parseInt(strings[i]) < Integer.parseInt(strings[i - 1])) { 
  8.                 strings[i - 1] = (Integer.parseInt(strings[i - 1]) - 1) + ""
  9.                 start = i; 
  10.             } 
  11.         } 
  12.         for (int i = start; i < strings.length; i++) { 
  13.             strings[i] = "9"
  14.         } 
  15.         return Integer.parseInt(String.join("",strings)); 
  16.     } 

java版本1中創建了String數組,多次使用Integer.parseInt了方法,這導致不管是耗時還是空間占用都非常高,用時12ms,下面提供一個版本在char數組上原地修改,用時1ms的版本

  1. 版本2 
  2. class Solution { 
  3.     public int monotoneIncreasingDigits(int n) { 
  4.         if (n==0)return 0; 
  5.         char[] chars= Integer.toString(n).toCharArray(); 
  6.         int start=Integer.MAX_VALUE;//start初始值設為最大值,這是為了防止當數字本身是單調遞增時,沒有一位數字需要改成9的情況 
  7.         for (int i=chars.length-1;i>0;i--){ 
  8.             if (chars[i]<chars[i-1]){ 
  9.                 chars[i-1]--; 
  10.                 start=i; 
  11.             } 
  12.         } 
  13.         StringBuilder res=new StringBuilder(); 
  14.         for (int i=0;i<chars.length;i++){ 
  15.             if (chars[i]=='0'&&i==0)continue;//防止出現09這樣的情況 
  16.             if (i>=start){ 
  17.                 res.append('9'); 
  18.             }else res.append(chars[i]); 
  19.         } 
  20.         return Integer.parseInt(res.toString()); 
  21.     } 

Python:

  1. class Solution: 
  2.     def monotoneIncreasingDigits(self, n: int) -> int
  3.         a = list(str(n)) 
  4.         for i in range(len(a)-1,0,-1): 
  5.             if int(a[i]) < int(a[i-1]): 
  6.                 a[i-1] = str(int(a[i-1]) - 1) 
  7.                 a[i:] = '9' * (len(a) - i)  #python不需要設置flag值,直接按長度給9就好了 
  8.         return int("".join(a)) 

Go

  1. func monotoneIncreasingDigits(N intint { 
  2.     s := strconv.Itoa(N)//將數字轉為字符串,方便使用下標 
  3.     ss := []byte(s)//將字符串轉為byte數組,方便更改。 
  4.     n := len(ss) 
  5.     if n <= 1 { 
  6.         return N 
  7.     } 
  8.     for i:=n-1 ; i>0; i-- { 
  9.         if ss[i-1] > ss[i] {//前一個大于后一位,前一位減1,后面的全部置為9 
  10.             ss[i-1] -= 1 
  11.             for j := i ; j < n; j++ {//后面的全部置為9 
  12.                 ss[j] = '9' 
  13.             } 
  14.         } 
  15.     } 
  16.     res, _ := strconv.Atoi(string(ss)) 
  17.     return res 

Javascript

  1. var monotoneIncreasingDigits = function(n) { 
  2.     n = n.toString() 
  3.     n = n.split('').map(item => { 
  4.         return +item 
  5.     }) 
  6.     let flag = Infinity 
  7.     for(let i = n.length - 1; i > 0; i--) { 
  8.         if(n [i - 1] > n[i]) { 
  9.             flag = i 
  10.             n[i - 1] = n[i - 1] - 1 
  11.             n[i] = 9 
  12.         } 
  13.     } 
  14.  
  15.     for(let i = flag; i < n.length; i++) { 
  16.         n[i] = 9 
  17.     } 
  18.  
  19.     n = n.join(''
  20.     return +n 
  21. }; 

 

責任編輯:姜華 來源: 代碼隨想錄
相關推薦

2020-10-30 09:56:59

Trie樹之美

2022-09-21 07:57:33

二叉搜索樹排序二叉樹

2022-09-26 07:56:53

AVL算法二叉樹

2020-10-21 14:57:04

數據結構算法圖形

2020-12-31 05:31:01

數據結構算法

2023-03-08 08:03:09

數據結構算法歸并排序

2020-10-20 08:14:08

算法與數據結構

2020-10-12 11:48:31

算法與數據結構

2023-10-27 07:04:20

2022-01-18 19:13:52

背包問題數據結構算法

2023-04-27 09:13:20

排序算法數據結構

2021-12-08 11:31:43

數據結構算法合并區間

2021-12-21 11:39:01

數據結構算法同構字符串

2009-08-11 14:43:42

C#數據結構與算法

2009-08-11 14:51:11

C#數據結構與算法

2021-07-16 04:57:45

Go算法結構

2023-03-07 08:02:07

數據結構算法數列

2023-03-10 08:07:39

數據結構算法計數排序

2023-03-02 08:15:13

2009-08-11 14:30:32

C#數據結構與算法
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 91国产精品 | 亚洲国产精品自拍 | 国产小视频在线观看 | 久久久国产精品网站 | 一二区成人影院电影网 | 久久综合影院 | 亚洲国产一区二区在线 | 一级片视频免费观看 | 日韩欧美大片在线观看 | 国产精品久久久久久吹潮日韩动画 | 伊人国产精品 | 偷拍自拍第一页 | 国产区免费视频 | 欧美中文字幕一区二区三区 | 污书屋| 一级做a爰片性色毛片16 | 国产目拍亚洲精品99久久精品 | 欧美黄色片 | 午夜寂寞影院列表 | 91精品免费 | 在线播放中文 | 日韩欧美中文 | 久久久久久中文字幕 | 久久99蜜桃综合影院免费观看 | 久久久久1 | 国产精品夜夜春夜夜爽久久电影 | 激情 婷婷 | 欧美一区二区三区在线观看视频 | 日本精品一区二区三区四区 | 日韩在线播放第一页 | 欧美日韩国产一区二区三区 | 一级网站 | 久久久久久国产免费视网址 | 日韩高清在线 | 欧美日韩在线观看一区二区三区 | 中文字幕视频在线观看 | 国产中文| 国产视频第一页 | 精品国产欧美在线 | 天天爱爱网 | 人人人干|