2971. Find Polygon With the Largest Perimeter
題目理解
題目連結:2971. Find Polygon With the Largest Perimeter
在這個問題中,我們需要找到一個多邊形,其邊長由整數陣列 nums
所組成,目的是找到這個多邊形的最大周長。如果無法形成多邊形,則回傳 -1。
題目限制
- 整數陣列
nums
的長度為n
。 3 <= n <= 10^4
。1 <= nums[i] <= 10^6
。
解題思路
根據題目敘述:
Conversely, if you havek
(k >= 3
) positive real numbersa1
,a2
,a3
, ...,ak
wherea1 <= a2 <= a3 <= ... <= ak
anda1 + a2 + a3 + ... + a(k-1) > ak
, then there always exists a polygon withk
sides whose lengths area1
,a2
,a3
, ...,ak
.
要形成一個有效的多邊形,最長邊必須小於其他剩餘邊的總和。
- 排序:首先將
nums
進行排序- 排序後可以保證每次選取的邊長都是從最小到最大的順序。
- 對於任意子陣列
nums[i..j]
,最長邊必定為nums[j - 1]
,則- 為了使邊長和最大化,應考慮最長邊為
nums[j - 1]
,其餘邊為nums[i..j - 2]
。 - 由於
i
必須從0
開始以確保最大的和,所以我們只需檢查每個長度為3
以上的子陣列。
- 為了使邊長和最大化,應考慮最長邊為
- 累積和檢查:在排序後,我們可以計算累積和以檢查是否滿足多邊形的條件
- 從第三個元素開始,每次計算前
i - 1
個元素的和sum
,檢查是否大於目前元素nums[i]
。 - 如果成立,則更新最大周長
ans
。 - 每次迭代將目前元素加入
sum
並進行下一次檢查,直到遍歷整個陣列。
- 從第三個元素開始,每次計算前
class Solution {
public:
long long largestPerimeter(vector<int>& nums) {
const int n = nums.size();
sort(nums.begin(), nums.end());
long long sum = nums[0] + nums[1];
long long ans = -1;
for (int i = 2; i < n; i += 1) {
if (sum > nums[i]) {
ans = max(ans, sum + nums[i]);
}
sum += nums[i];
}
return ans;
}
};
- 時間複雜度:
先對陣列進行排序需要O(n log n)
的時間,接著在排序完成後透過一次迴圈檢查是否能形成多邊形並計算周長,這部分是O(n)
。因整體主導花費為O(n log n)
,故最終時間複雜度為O(n log n)
。 - 空間複雜度:
除了排序在大多數情況下可視為就地(in-place)操作外,我們只需要常數個額外變數(像是sum
、ans
),因此空間複雜度為O(1)
。
Comments ()