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);
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律