這是悅樂書的第368次更新,第396篇原創
java
今天介紹的是LeetCode
算法題中Easy
級別的第230
題(順位題號是976
)。給定正長度的數組A
,返回具備非零區域的三角形的最大周長,由這些長度中的3個組成。若是不可能造成任何非零區域的三角形,則返回0。例如:算法
輸入:[2,1,2]
輸出:5數組
輸入:[1,2,1]
輸出:0數據結構
輸入:[3,2,3,4]
輸出:10優化
輸入:[3,6,2,3]
輸出:8code
注意:排序
3 <= A.length <= 10000class
1 <= A[i] <= 10^6
數據結構與算法
暴力解法,會超時。循環
題目的意思是從數組中拿三個數組成三角形,求最大周長,若是找不到適合的數組成三角形,就返回0。直接上循環,取三個數,拿到三個數後,利用三角形的定義:任意兩邊之和大於第三邊,任意兩邊之差小於第三邊。符合這兩個條件就求三個數之和,最後取其中的最大值輸出。
此解法的時間複雜度是O(N^3)
,空間複雜度是O(1)
。
public int largestPerimeter(int[] A) { int max = 0, len = A.length; for (int i=0; i<=len-2; i++) { for (int j=i+1; j<len-1; j++) { for (int k=j+1; k<len; k++) { if (isTriangle(A[i], A[j], A[k])) { max = Math.max(max, A[i]+A[j]+A[k]); } } } } return max; } public boolean isTriangle(int x, int y, int z) { boolean f = false, f2 = false; // 任意兩邊之和大於第三邊 if (x+y>z && x+z>y && y+z>x) { f = true; } // 任意兩邊之差小於第三邊 if (x-y<z && x-z<y && y-z<x) { f2 = true; } return f && f2; }
第一種解法的時間複雜度過高了,咱們須要再優化下,既然是數組,而且須要一次拿三個數,那可以想到的就是先排序了,取相鄰的三個元素,以這三個元素做爲三角形的邊長a、b、c,他們的大小關係是a<=b<=c
,若是想要a、b、c
組成三角形,須要知足什麼條件?
第一種狀況:等邊三角形,即a=b=c
,例如{3,3,3}。
第二種狀況:等腰三角形,即a=b
或者b=c
,例如{4,4,5}、{2,6,6}。
第三種狀況:普通三角形,即a<b<c
,例如{3,4,5}能夠組成三角形,可是像{3,4,8}就不能組成三角形,雖然3,4,8知足a<b<c的關係。
因此,若是有a<=b<=c
的前提,那麼只要a+b>c
,就能夠組成三角形。
思路:利用Arrays
的sort
方法,對A
排序,從後往前每次取三個數,判斷是否知足a+b>c
,知足此條件的三個數組成的三角形的周長是最大的。
此解法的時間複雜度是O(NlogN)
,空間複雜度是O(1)
。
public int largestPerimeter2(int[] A) { Arrays.sort(A); int n = A.length; for (int i=n-3; i>=0; i--) { if (A[i] + A[i+1] > A[i+2]) { return A[i] + A[i+1] + A[i+2]; } } return 0; }
算法專題目前已連續日更超過七個月,算法題文章236+篇,公衆號對話框回覆【數據結構與算法】、【算法】、【數據結構】中的任一關鍵詞,獲取系列文章合集。
以上就是所有內容,若是你們有什麼好的解法思路、建議或者其餘問題,能夠下方留言交流,點贊、留言、轉發就是對我最大的回報和支持!