[LeetCode 611.] Valid Triangle Number

LeetCode 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:

  1. The length of the given array won't exceed 1000.
  2. The integers in the given array are in the range of [0, 1000].

解题思路

首先想到的是暴力枚举所有的三元组,但是三层循环、并且每个三元组都需要三次三角不等式判断,肯定是不可接受的,所有我们可以有以下优化:

  1. 可以先排序,然后 i<j<k 的约束条件下,就只需要判断 nums[i] + nums[j] > nums[k] 这一个不等式就可以了;
  2. 又注意到数组有序,这样当某一个k不满足条件,后续的k都将不满足条件,可以提前结束 k 循环;
  3. 在有序数组中,前半段满足条件后半段不满足条件的判断,可以用二分查找进一步优化。

参考代码

对于优化1和优化2,我们有以下代码:

/*
 * @lc app=leetcode id=611 lang=cpp
 *
 * [611] Valid Triangle Number
 */

// @lc code=start
class Solution {
public:
    int triangleNumber(vector<int>& nums) {
        size_t n = nums.size();
        int cnt = 0;
        sort(nums.begin(), nums.end());
        for (int i=0; i+2<n; i++) {
            for (int j=i+1; j+1<n; j++) {
                for (int k=j+1; k<n; k++) {
                    if (nums[i] + nums[j] <= nums[k]) {
                        break;
                    }
                    cnt ++;
                }
            }
        }
        return cnt;
    } // AC, O(N^3)
};
// @lc code=end

加入优化3,代码如下:

/*
 * @lc app=leetcode id=611 lang=cpp
 *
 * [611] Valid Triangle Number
 */

// @lc code=start
class Solution {
public:
    int triangleNumber(vector<int>& nums) {
        size_t n = nums.size();
        int cnt = 0;
        sort(nums.begin(), nums.end());
        for (int i=0; i+2<n; i++) {
            for (int j=i+1; j+1<n; j++) {
                auto start = nums.begin()+j+1;
                auto it = lower_bound(start, nums.end(), nums[i]+nums[j]);
                cnt += it - start;
            }
        }
        return cnt;
    } // AC, O(N^2 * logN)
// lower_bound 二分查找返回元素第一次出现位置,或者第一个大于该元素的位置
};
// @lc code=end
posted @ 2021-03-27 19:18  与MPI做斗争  阅读(28)  评论(0编辑  收藏  举报