有效三角形个数与和为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};
    }
}

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

相关推荐
海上小飞龙10 小时前
【KMP算法-下篇】同一道题:Java 库函数 2600 微秒,手写 KMP 16 微秒
java·开发语言·算法
青少儿编程课堂10 小时前
后缀自动机解析:本质不同子串与最长重复片段统计
c++·python·算法·bfs·信息学竞赛
朝朝辞暮i10 小时前
C++ 第 12 课:局部变量、作用域、变量生命周期
开发语言·c++·算法
乐迪信息11 小时前
港口船舶逆行怎么管?AI防爆摄像机搭载智能检测算法
大数据·人工智能·深度学习·算法·计算机视觉
Sirens.12 小时前
Java并发锁详解:六类锁策略与 synchronized 底层原理
java·前端·算法
和裕13 小时前
全纸结构重型纸箱能否满足 1 吨以上设备出口熏蒸豁免要求?通关合规性全解析
大数据·运维·网络·人工智能·算法
tangguofeng13 小时前
不带头结点的链队操作集(不含InitFlag)(C语言版)
算法
苏打豆15 小时前
CRISP源码阅读——基于ROS2力矩反馈控制器与速度加速度零空间
c++·线性代数·算法·矩阵·机器人
蛋蛋的就会顺顺的15 小时前
hot100——矩阵
java·数据结构·算法·leetcode·力扣