有效三角形个数与和为s的两个数字

五、有效三角形的个数

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

示例

题目要求返回所有数组中可以组成有效三角形的元素组合。

最简单的解法就是暴力枚举,列出所有组合,记录下可以组成三角形的三元组个数。

示例一的解析给出两次相同组合,说明虽然两个元素值一样,但是下标不一样,也可以算作一组。

直接套三层循环暴力过掉。

代码:

java 复制代码
class Solution {
    public int triangleNumber(int[] nums) {
        int count=0;
        for(int a=0;a<nums.length;a++){
            for(int b=1;b<nums.length;b++){
                for(int c=2;c<nums.length;c++){
                    while(b<=a){
                        b++;
                    }
                    while(c<=b){
                        c++;
                    }
                    if(c>=nums.length){
                        break;
                    }
                    if((nums[a]+nums[b])>nums[c]){
                        if ((nums[a]+nums[c])>nums[b]){
                            if ((nums[b]+nums[c])>nums[a]){
                                count++;
                            }
                        }
                    }
                }
            }
        }
        return count;
    }
}

但是肯定报错,时间复杂度起步 O(n³) ,必然超时。

需要想一个更优解法。

题目说明所有的用例都是非负整数,那就可以给数组先排序,再进行遍历。

乱序数组很难找出规律,而且最主要的原因在于不能移动,因为保证不了移动后的整数大小。

这里用一组暴力解法报错的例子找更优解。

刚才说了,乱序数组无法向不确定大小的位置移动寻找有效三角形,所以先让数组排序。

此时再基于三层循环的思路做优化。

让三个指针分别指向数组左右侧

如果写过盛水最多的容器题目,那应该能想到用指针优化这题。

我们固定 a ,让 b 移动,会发现两种情况。

若是最小的数加上这个区间里最大的数依旧小于等于 C ,那么 a 要向右移。

反之,这个区间里的数都不用算了,全是有效三角形。

完成一次循环后,C 的位置向左移一格,继续寻找有效三角形,直到 C 移到2的位置。

优化后的代码:

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

六、和为s的两个数字

购物车内的商品价格按照升序记录于数组 price。请在购物车中找到两个商品的价格总和刚好是 target。若存在多种情况,返回任一结果即可。

这是一道简单题,暴力解法依旧两层循环枚举,同时肯定超时。

代码:

java 复制代码
class Solution {
    public int[] twoSum(int[] price, int target) {
        int[] arr={-1,-1};
        for(int i=0;i<price.length;i++){
            for(int j=1;j<price.length;j++){
                if((price[i]+price[j])==target && price[i]!=price[j]){
                    arr[0]=price[i];
                    arr[1]=price[j];
                }
            }
        }
        return arr;
    }
}

优化解法依旧采用双指针。

由于数组升序排列降低了很多难度,所以不用考虑这么多,直接把指针放在左右两侧。

等到和为 target ,把这两个整数放到一个新数组里返回。

代码:

java 复制代码
class Solution {
    public int[] twoSum(int[] price, int target) {
        int left=0,right=price.length-1;
        while(left<right){
            int sum=price[left]+price[right];
            if(sum==target){
                return new int[] {price[left],price[right]};
            }else if(sum>target){
                right--;
            }else{
                left++;
            }
        }
        return new int[]{0};
    }
}

注意一下,如果返回值写在循环体里,外边一定要再给一个返回值,否则编译器会认为可能没有返回值从而报错。

相关推荐
好悬给我拽开线1 小时前
ZILOT 论文解析
算法
饮水桶_T2 小时前
JAVA IO流笔记
开发语言·数据结构·算法
星夜离尘563 小时前
MATLAB 离散数据分箱:半开区间、末端点与计数、加权和、平均
算法·matlab
Pniubi3 小时前
力扣76.最小覆盖子串
算法·leetcode·职场和发展
地平线开发者4 小时前
征程6|用 hrt\_model\_exec 看清 YOLOv5x 的输入、原始输出和后处理
人工智能·算法
csdn_aspnet5 小时前
C++ 3个有序点的方向(Orientation of 3 ordered points)
c++·算法
赤生云电竞5 小时前
GPU算力共享平台架构实践:任务分发与资源隔离的关键配置
算法·架构·gpu算力
青少儿编程课堂6 小时前
蓝桥杯·全国青少年信息素养大赛·电子学会Python/C++考级:折半搜索优化子集枚举(Meet in the Middle)解析
c++·python·算法·bfs·信息学竞赛
Oneshot9 小时前
DLX(Dancing Links)算法详解:求解数独最快的算法
算法
青少儿编程课堂9 小时前
蓝桥杯青少组图形化 + 全国青少年信息素养大赛 + 电子学会Scratch考级:校园连连看解析
c++·python·算法·bfs·信息学竞赛