返回

算法:有效三角形的个数

前端

引言

在数学中,三角形是一个由三条边和三个角组成的多边形。三角形是最简单的多边形,也是最常见的几何图形之一。三角形的面积和周长是三角形两个重要的属性。三角形在数学、物理、工程等领域都有着广泛的应用。

问题

给定一个包含非负整数的数组,统计其中可以组成三角形三条边的三元组个数。

解决方案

方法一:暴力枚举

public int triangleNumber(int[] nums) {
    int count = 0;
    for (int i = 0; i < nums.length; i++) {
        for (int j = i + 1; j < nums.length; j++) {
            for (int k = j + 1; k < nums.length; k++) {
                if (nums[i] + nums[j] > nums[k] && nums[i] + nums[k] > nums[j] && nums[j] + nums[k] > nums[i]) {
                    count++;
                }
            }
        }
    }
    return count;
}

方法二:排序+双指针

public int triangleNumber(int[] nums) {
    Arrays.sort(nums);
    int count = 0;
    for (int i = 0; i < nums.length - 2; i++) {
        int left = i + 1, right = nums.length - 1;
        while (left < right) {
            if (nums[i] + nums[left] > nums[right]) {
                count += right - left;
                right--;
            } else {
                left++;
            }
        }
    }
    return count;
}

方法三:动态规划

public int triangleNumber(int[] nums) {
    int n = nums.length;
    int[][] dp = new int[n][n];
    Arrays.sort(nums);
    for (int i = 0; i < n; i++) {
        dp[i][i] = 1;
    }
    for (int i = n - 2; i >= 0; i--) {
        for (int j = i + 1; j < n; j++) {
            for (int k = j + 1; k < n; k++) {
                if (nums[i] + nums[j] > nums[k]) {
                    dp[i][j] += dp[j][k];
                }
            }
        }
    }
    int count = 0;
    for (int i = 0; i < n; i++) {
        for (int j = i + 1; j < n; j++) {
            count += dp[i][j];
        }
    }
    return count;
}

算法分析

方法一:暴力枚举

时间复杂度:O(n^3),其中n为数组的长度。

空间复杂度:O(1)。

方法二:排序+双指针

时间复杂度:O(n^2),其中n为数组的长度。

空间复杂度:O(1)。

方法三:动态规划

时间复杂度:O(n^3),其中n为数组的长度。

空间复杂度:O(n^2)。

结论

在这篇文章中,我们讨论了如何给定一个包含非负整数的数组,统计其中可以组成三角形三条边的三元组个数。我们介绍了三种解决该问题的算法:暴力枚举、排序+双指针和动态规划。我们还分析了这三种算法的时间复杂度和空间复杂度。


附录