Week5
Program--Medium--611. Valid Triangle Number
Given an array consists of non-negative integers, your task is to count the number of triplets chosen from the array that can make triangles if we take them as side lengths of a triangle.
Example 1:
Input: [2,2,3,4] Output: 3 Explanation: Valid combinations are: 2,3,4 (using the first 2) 2,3,4 (using the second 2) 2,2,3
Note:
- The length of the given array won't exceed 1000.
- The integers in the given array are in the range of [0, 1000].
题目解析:
这是一个简单的匹配问题,如果时间允许的话,用一个三重循环即可解决,再用三角形判定定理“任意一边都小于其余两边之和”来进行判定即可。
代码:
class Solution {
public:
int triangleNumber(vector<int>& nums) {
int count = 0;
if (nums.size() < 3) {
return 0;
}
for (int i = 0; i < nums.size() - 2; i++) {
if (nums[i] <= 0) {
continue;
}
for (int j = i + 1; j < nums.size() - 1; j++) {
if (nums[j] <= 0) {
continue;
}
for (int k = j + 1; k < nums.size(); k++) {
if (nums[k] <= 0) {
continue;
}
if (isTriangle(nums[i], nums[j], nums[k])) {
count++;
}
}
}
}
return count;
}
bool isTriangle(int a, int b, int c) {
if (a+b>c&&b+c>a&&c+a>b) {
return true;
} else {
return false;
}
}
};
优化算法:
通过观察,我们可以知道,在一个有序序列num中,设i = start, k = end, j = end - 1。
1.如果(1)num[i] + num[j] > num[k],那么对于i = start+1——end-2,num[i] + num[j] > num[k]也成立,而且显然num[j] + num[k] > num[i],num[i] + num[k] > num[j]。所以,所有位于i——j-1共(j-i)个数的数与num[j],num[k]也可以构成三角形,相当于减少了一层确定最小值的遍历循环。然后j--,使得(1)式左边变小,看是否还符合。
2.如果条件不成立,证明(1)左边太小,因此i++,增加左边的值,继续判断。
上诉步骤是内层循环,用于两个较小值的确定,最外层循环则是第三个数最大数的确定,这样,算法复杂度就有O(N^3)变为O(N^2)。
代码:
class Solution {
public:
int triangleNumber(vector<int>& nums) {
sort(nums.begin(), nums.end());
int count = 0;
for (int k = nums.size() - 1; k > 1; k--) {
int i = 0, j = k - 1;
while(i < j) {
if (nums[i] + nums[j] > nums[k]) {
j--;
count += j - i + 1;
} else {
i++;
}
}
}
return count;
}
};