LeetCode 11盛水最多的容器12整数转罗马数字
目錄
- 盛水最多的容器
- 題目描述
- 分析
- 整數轉羅馬數字
- 題目描述:
- 分析
- 結語
盛水最多的容器
公眾號:bigsai,回復進群加入打卡,回復bigsai獲取3GB的pdf資源。點贊再看,養成習慣!
題目描述
給你 n 個非負整數 a1,a2,…,an,每個數代表坐標中的一個點 (i, ai) 。在坐標內畫 n 條垂直線,垂直線 i 的兩個端點分別為 (i, ai) 和 (i, 0)。找出其中的兩條線,使得它們與 x 軸共同構成的容器可以容納最多的水。
說明:你不能傾斜容器,且 n 的值至少為 2。
示例:
輸入:[1,8,6,2,5,4,8,3,7]
輸出:49
分析
對于這題來說,要求是求能夠組成容器最大面積(忽略寬度)。直白的講就是從若干個數字中找到一對數字,它們的距離和較小的數字成績最大。
越好的情況就是數字很大(高度很高),并且距離也足夠長!但是也很可能出現最大的在中間的情況:
思路一:
這題可以使用暴力的方法求解,枚舉所有可能的情況,我們知道每個容器需要兩根柱子組成,我們每次遍歷柱子讓當前柱子成為最矮的,去找最長的那個計算結果。當然這個結果可能是左側,也可能是右側。所以要找到遠的那個比當前數字大的結果與max進行比較即可。
在具體的實現方面,注意一下相鄰距離為1就可以啦:
不過效果很差……
這種方法就是沒任何進步的方法。
思路二:
這題其實可以從兩側雙指針動態試探,初始情況沒什么疑問,但是下一次到底是左面指針向右移動還是右側指針向左移動呢?你要清楚:
- 無論左移還是右移動,數字之間的區間都是減小的(距離縮小)
- 如果移動較大的那個,下一次移動結果一定不可能大于這一次結果!(就算你的下一個很高,但是要根據最矮的來)
- 所以我們每次移動,把較小的那個指針向中間移動,尋找更大的可能
你可能會擔心,這樣看從一個位置元素來看確實滿足,會不會你這樣漏了更好的,當然不會,我說了當前情況是這個矮個子能夠到達的最大情況,已經是一個極限,想要突破這個極限,就只能去找更高的組合。
實現代碼為(具體可以看我另一篇優化的思路):
public int maxArea(int[] height) {int max = 0;int left = 0;int right = height.length - 1;int team = 0;int len = height.length;int leftvalue=0;int rightvalue=0;while (len-- > 0) {leftvalue=height[left];rightvalue=height[right];if (leftvalue < rightvalue) {team = leftvalue * len;if(max<team) {max=team;}left++;} else {team = rightvalue * len;if(max<team) {max=team;}right--;}}return max;}效果良好:
整數轉羅馬數字
題目描述:
羅馬數字包含以下七種字符: I, V, X, L,C,D 和 M。
例如, 羅馬數字 2 寫做 II ,即為兩個并列的 1。12 寫做 XII ,即為 X + II 。 27 寫做 XXVII, 即為 XX + V + II 。
通常情況下,羅馬數字中小的數字在大的數字的右邊。但也存在特例,例如 4 不寫做 IIII,而是 IV。數字 1 在數字 5 的左邊,所表示的數等于大數 5 減小數 1 得到的數值 4 。同樣地,數字 9 表示為 IX。這個特殊的規則只適用于以下六種情況:
- I 可以放在 V (5) 和 X (10) 的左邊,來表示 4 和 9。
- X 可以放在 L (50) 和 C (100) 的左邊,來表示 40 和 90。
- C 可以放在 D (500) 和 M (1000) 的左邊,來表示 400 和 900。
給定一個整數,將其轉為羅馬數字。輸入確保在 1 到 3999 的范圍內。
分析
對于這題,其實就是一個數字和字符串處理的問題。規則和進制準換很相似 ,思路也大體一致——不斷整除和求余,只不過要考慮5和10的兩種特殊情況:
- 對于5種類來說除數的結果一定是4并且當前滿足為偶數位(0,2,4等位)(比如處理4時候4/1=4,40/10=4)
- 對于10種類來說除數的結果為1,且加上比它小一位的數和為比它大一位的數(比如9/5=1,9+1=10),且都在奇數位上。
有了上述方法找到對應位置的數就可以進行操作了,記住疊加羅馬數字一定別用String而要用StringBuilder。
實現代碼為:
public static String intToRoman(int num) {int numvalue []={1,5,10,50,100,500,1000};char charvalue []= {'I', 'V', 'X', 'L','C','D','M'};StringBuilder sBuilder=new StringBuilder();int team=0;for(int i=numvalue.length-1;i>=0;i--){team=num/numvalue[i];if(team==4&&i%2==0) {//向上進一為sBuilder.append(charvalue[i]); sBuilder.append(charvalue[i+1]); num=num%numvalue[i];}else if (team==1&&i%2==1&&(num+numvalue[i-1])/numvalue[i+1]==1) {sBuilder.append(charvalue[i-1]);sBuilder.append(charvalue[i+1]);num%=numvalue[i-1];}else {for(int j=0;j<team;j++){sBuilder.append(charvalue[i]);}num=num%numvalue[i];}}return sBuilder.toString(); }效果還不錯!
結語
原創不易,bigsai我請你幫兩件事幫忙一下:
star支持一下, 您的肯定是我在平臺創作的源源動力。
微信搜索「bigsai」,關注我的公眾號,不僅免費送你電子書,我還會第一時間在公眾號分享知識技術。加我還可拉你進力扣打卡群一起打卡LeetCode。
記得關注、咱們下次再見!
總結
以上是生活随笔為你收集整理的LeetCode 11盛水最多的容器12整数转罗马数字的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: LeetCode精讲题 10正则表达式匹
- 下一篇: 刷题一个4ms的程序,代码如何优化到3m