阅读 112

算法:有效三角形的个数

题目

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

1.  数组长度不超过1000
2.  数组里整数的范围为 [0, 1000]

输入: [2,2,3,4]
输出: 3
解释:
有效的组合是: 
2,3,4 (使用第一个 2)
2,3,4 (使用第二个 2)
2,2,3复制代码

分析

构成三角形的条件:

任意两条边的和大于第三条边,任意两条边的差小于第三条边

1. 暴力循环

暴力的三层循环查找,在每一层的值当做是三角形的一条边,然后再去判断三个值是否满足构成三角形的条件

function getCount (array) {
    const L = array.length;
    let count = 0;
    for(let i = 0; i<L-2; i++) {
        // 第一条边
        const first = array[i];
        for(let m = i + 1; m<L-1; m ++ ) {
             // 第二条边
            const second = array[m];
            for(let n = m+1; n< L; n++) {
                // 第三条边
                const third = array[n];
                // 判断是否满足三角形的条件
                if(first + second > third && first + third > second && second + third > first) {
                    count ++ ;
                }
            }
        }
    }

    return count;
}复制代码

2. 排序 + 双指针

将数组进行从小到大的排序。 固定一条边,另外两条边依次的向右移动。

  1. 我们使用一重循环枚举 i。当 i 固定时,我们使用双指针同时维护 jk,它们的初始值均为 i

  2. 我们每一次将 j 向右移动一个位置,即 j + 1,并尝试不断向右移动 k,使得 k 是最大的满足array[k] < array[i] + array[j],我们将 Math.max(k - j, 0) 累加。

指针 k 不会出现在指针 j 的右侧,即 k - j ≤ 0

function getCount(array) {
    const n = array.length;
    array.sort((a, b) => a - b);
    let count = 0;
    for (let i = 0; i < n; ++i) {
        let k = i;
        for (let j = i + 1; j < n; ++j) {
            while (k + 1 < n && array[k + 1] < array[i] + array[j]) {
                ++k;
            }
            count += Math.max(k - j, 0);
        }
    }
    return count;
};复制代码

结语


作者:forever_Mamba
链接:https://juejin.cn/post/7024327687195852814


文章分类
后端
版权声明:本站是系统测试站点,无实际运营。本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 XXXXXXo@163.com 举报,一经查实,本站将立刻删除。
相关推荐