24.<tag-数组和简单的遍历, 双指针>-lt- 674. 最长连续递增序列 + lt- 611. 有效三角形的个数 + lt-628. 三个数的最大乘积 ☆

lt- 674. 最长连续递增序列

[案例需求]
在这里插入图片描述

[思路分析]

  • 根据题目可知, 我们是对最长的连续递增序列进行计数, 所以肯定要维护一个计数器, 可以设置一个变量count作为计数, 由于数组中的连续递增序列有多个, 所以我们肯定还要另外设置一个res作为答案,
  • 每遍历完其中的一个连续递增序列, 首先count设置为1(最短长度为1), 因为后面还会有递增序列等待遍历, 然后每次对cout遍历完之后, 就要去那count与res对比大小, 更新出较大的res;

[代码示例]

class Solution {
    public int findLengthOfLCIS(int[] nums) {

        //剪枝
        if(nums.length <= 1) return 1;

        int count = 0, ans = 0;

        for(int i = 0; i < nums.length; i++){
            if(i >= 1 && nums[i] > nums[i - 1]){
                count++;
            }else{
                count = 1;
            }

            ans = count > ans ? count : ans;
        }

        return ans;
    }
}

另外一种写法

//4.19 莫名奇妙的 解法
class Solution {
    public int findLengthOfLCIS(int[] nums) {

        int res = 1;
        int len = nums.length;
     
        int count = 1;
        int i = 1;

        while(i < len ){
            count = 1;
        
            while(i < len && nums[i] - nums[i - 1] > 0){
                ++count;
                ++i;
            }
            ++i;
            res = Math.max(count, res);
            
        }
        return res;
    }
}

面试改编真题

在这里插入图片描述

lt- 611. 有效三角形的个数

[案例需求]
在这里插入图片描述

[思路分析]
根据题意,是要我们统计所有符合 nums[k] + nums[j] > nums[i] 条件的三元组 (k,j,i) 的个数。

为了防止统计重复的三元组,我们可以先对数组进行排序,然后采取「先枚举较大数;在下标不超过较大数下标范围内,找次大数;在下标不超过次大数下标范围内,找较小数」的策略。

  • 所以可以先对数组进行排序, 然后倒序遍历数组, 先固定一个数作为最大值, 然后用对撞双指针寻找能构成三角形的三个数的范围.
  • 比如 2,2,3,4, 第一次, for循环倒序遍历, i = 3, left = 0, right = i - 1 = 2;
  • nums[left] = nums[0] = 2, nums[right] = nums[2] = 3, nums[i] = 4;
  • left --> right 之间一定都是可以形成三角形的数 (因为nums[left] + nums[right] > nums[i])
    [代码实现一]
class Solution {
    public int triangleNumber(int[] nums) {
        //排序
        Arrays.sort(nums);

        //for循环 + 双指针
        int len = nums.length;

        int count = 0;

        for(int i = len - 1; i >= 2; i--){
            int right = i - 1;
            int left = 0;

            while(left < right){
            	//当前left位置满足条件(a + b > c), 计算count后, right后移即可
                if(nums[left] + nums[right] > nums[i]){
                    count += (right - left); 
                    --right;
                }else{//当前left不满足条件, ++left, 寻找可满足的left
                    ++left;
                }
                
            }
        }
        return count;
    }
}
class Solution {
    public int triangleNumber(int[] nums) {
        //剪枝
        if(nums.length < 3) return 0;
        
        //排序
        Arrays.sort(nums);

        //倒序遍历/
        //左右指针做前两个加数, 遍历索引做第三个加数
        // 左 + 右 > 索引加数    count++;
        // left -> right 逼近

        int left,right = 0;
        int count = 0;
        for(int i = nums.length - 1; i >= 2; i--){
            left = 0;
            right = i - 1;

            while(left < right){
                if(nums[left] + nums[right] > nums[i]){
                   // ++count; 这里不对噢!!!
                    count += (right - left);
                   // ++left;
                   --right;
                }else{
                    left++;
                }
            }
        }

        return count;
    }
}

在这里插入图片描述

X.<tag-数组和二分查找>-lt.xx-xxxxxx + lt.xx-xxxxxx

lt-628. 三个数的最大乘积

[案例需求]
在这里插入图片描述

[思路分析一, 排序后比较乘积]

  • 由题, 给定的数组中既含有负数, 又含有正数, 因为求三个数成绩的最大值, 所以三个整数, 两个负数和一个整数都有可能构成最大的乘积, 所以一个比较简单的思路就是对整个数组先进行排序, 然后找出数组最后的三个数, 和前两个负数和最后一个数的成绩进行比较, 大的那个肯定就是三个数的最大乘积;

思路二, 一层循环遍历, 找出整个数组中两个最小的值, 和三个最大的值;
这种写法之前经常碰到, 用特定的几个变量记录最大值和次大值, 如果找到一个数比最大值大了, 就要把当前的最大值移交给次大值, 然后把找到的这个数记录到最大值中(权利的交接嘛)

[代码实现]


class Solution {
    public int maximumProduct(int[] nums) {
        ///1. 排序法
        // Arrays.sort(nums);
        // int len = nums.length;
        // return Math.max( nums[len-1] * nums[len - 2] * nums[len - 3], nums[0] * nums[1] * nums[len-1]);

        //2. 求出数组中最大的三个数以及最小的两个数,因此我们可以不用排序,用线性扫描直接得出这五个数。
        int min1 = Integer.MAX_VALUE, min2 = Integer.MAX_VALUE;
        int max1 = Integer.MIN_VALUE, max2 = Integer.MIN_VALUE, max3 = Integer.MIN_VALUE;

        for(int i = 0; i < nums.length; i++){
            int x = nums[i];

            if(x < min1){
                min2 = min1;
                min1 = x;
            }else if (x < min2){
                min2 = x;
            }

            if(x > max1){
                max3 = max2;
                max2 = max1;
                max1 = x;
            }else if(x > max2){
                max3 = max2;
                max2 = x;
            }else if(x > max3){
                max3 = x;
            }
        }
        return Math.max(max1*max2*max3, min1*min2*max1);
    }
}
posted @   青松城  阅读(19)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律
点击右上角即可分享
微信分享提示