首页 > 其他分享 >leecode-day6

leecode-day6

时间:2023-04-10 20:00:37浏览次数:44  
标签:乘积 nums day6 int leecode values 数组 prices

1. 152乘积最大连续子数组

题目描述:
给你一个整数数组 nums ,请你找出数组中乘积最大的非空连续子数组(该子数组中至少包含一个数字),并返回该子数组所对应的乘积。
测试用例的答案是一个 32-位 整数。
子数组 是数组的连续子序列。
152乘积最大连续子数组

思路:
这道题跟day5的连续子数组最大和有点类似,感觉可以说是它的变形。
如果我们仅仅使用连续子数组最大和的方法,假设数组全是正数,也是可以得到正确结果的,但是假设出现,a,b,c,d是连续的子数组值,axb<0,c>0,d<0,c>max(|a|,|b|)此时c的dp=c,而d的dp也=c,但是我们知道这时候的连续子数组的最大乘积应该是abcd的乘积。

上述例子我们可以知道,因为涉及到正负数的问题,所以可能导致我们的结果出错,所以我们考虑把正负数分开计算。对于一个正数来说,最大连续子数组的乘积应该等于 以它前一个数组值结尾的连续子数组的最大乘积 与它的乘积和它本身的最大值,对于负数来说,最大连续子数组的乘积应该等于 以它前一个数组值结尾的连续子数组的最小乘积与它的乘积 和它本身的最大值。文字有点抽象,先用代码表示再解释。

        int maxValue = nums[0], minValue = nums[0];
        int[] max = new int[nums.length];//以i结尾的最大连续子数组乘积
        int[] min = new int[nums.length];//以i结尾的最小连续子数组乘积
        max[0] = min[0] = nums[0];
        for (int i = 1; i < nums.length; i++) {
            int tmp = nums[i];
            if (tmp > 0) {
                max[i] = Math.max(max[i - 1] * tmp, tmp);
                min[i] = Math.min(min[i - 1] * tmp, tmp);
            } else {
                max[i] = Math.max(min[i - 1] * tmp, tmp);
                min[i] = Math.min(max[i - 1] * tmp, tmp);
            }
            maxValue = Math.max(max[i], maxValue);
        }

对于一个负数来说,要获取以他结尾的连续子数组最大乘积,就需要获取以她前一个结尾的连续子数组最小乘积,假设之前的最小乘积是负数,一个负数✖️一个最小的负数就可以得到一个最大的正数;假设之前的最小乘积是正数,一个负数乘以一个最小的正数所得到的负数也是最大的负数,是以当前数值结尾的最大的乘积。

所以说我们需要两个数组dp,连续子数组最大乘积和连续子数组最小乘积,并且维护他们的值。维护这两个数组的值需要分成两种情况。第一种是当前结尾的数值大于0,此时两个数组的维护方法跟连续子数组最大和一样。第二种是以当前结尾的数值小于0,我们所取得需要乘起来的数组就刚好相反。

2. 1567乘积为正的最长子数组长度

题目描述:
给你一个整数数组 nums ,请你求出乘积为正数的最长子数组的长度。

一个数组的子数组是由原数组中零个或者更多个连续数字组成的数组。

请你返回乘积为正数的最长子数组长度。

链接:1567乘积为正的最长子数组长度

思路:
这题跟152类似,因为乘积涉及到正负数,需要定义两个dp,分别是以i结尾的乘积为正数的最长子数组长度和以i结尾的乘积为负数的最长子数组长度,代码如下:

        int[] productUp = new int[nums.length];//以i结尾的乘积为正数的最长子数组长度
        int[] productDown = new int[nums.length];//以i结尾的乘积为负数的最长子数组长度
        if (nums[0] > 0)
            productUp[0] = 1;
        else if (nums[0] < 0)
            productDown[0] = 1;
        int maxCount = productUp[0];
        for (int i = 1; i < nums.length; i++) {
            if (nums[i] > 0) {
                productUp[i] = productUp[i - 1] + 1;
                productDown[i] = productDown[i - 1] > 0 ? productDown[i - 1] + 1 : 0;
            } else if (nums[i] < 0) {
                productDown[i] = productUp[i - 1] + 1;
                productUp[i] = productDown[i - 1] > 0 ? productDown[i - 1] + 1 : 0;
            } else {
                productDown[i] = 0;
                productUp[i] = 0;
            }
            maxCount = Math.max(maxCount, productUp[i]);
        }

首先初始化,如果第一个数组值大于0,那么给正数dp赋初值1,小于0则给负数dp赋初始值1.

然后如果当前值为正数,则正数dp值为它前一个结尾的正数dp的长度加1,负数dp的值为 如果它前面有连续的乘积为负数子数组,则在此基础上加一,否则置0。当值为负数时类似。当当前值是0时,需要特殊判断,此时两个dp的值都是0。

3. 1014最佳观光组合

题目描述:
给你一个正整数数组 values,其中 values[i] 表示第 i 个观光景点的评分,并且两个景点 i 和 j 之间的 距离 为 j - i。

一对景点(i < j)组成的观光组合的得分为 values[i] + values[j] + i - j ,也就是景点的评分之和 减去 它们两者之间的距离。

返回一对观光景点能取得的最高分。

链接

思路:
这题印象太深刻了,感觉是一道数学题。
直接写代码吧,有兴趣看下官方给的题解。

        int[] points = new int[values.length];//以景点i结尾的官网景点的评分
        points[1] = values[1]+values[0]-1;
        int pointMax = points[1];
        int maxI = values[0]>values[1]+1?values[0]:values[1]+1;
        //values[j]+values[i]+i-j  (i<j)
        for (int i = 2; i < values.length; i++) {
            points[i] = maxI+values[i]-i;
            maxI = Math.max(values[i]+i,maxI);
            pointMax = Math.max(pointMax,points[i]);
        }
        return pointMax;

4. 121买卖股票的最佳时机

题目描述:
给定一个数组 prices ,它的第 i 个元素 prices[i] 表示一支给定股票第 i 天的价格。

你只能选择 某一天 买入这只股票,并选择在 未来的某一个不同的日子 卖出该股票。设计一个算法来计算你所能获取的最大利润。

返回你可以从这笔交易中获取的最大利润。如果你不能获取任何利润,返回 0 。

链接

思路:
在一次遍历的时候,我们记录下股票最低价,然后遍历到每个值的时候都看当前价格与最低价的差值是不是最大的。

        int maxProfit  = 0;
        int lowValue = prices[0];
        for (int i = 1; i < prices.length; i++) {
            int currentMax  = 0;
            if (prices[i]> lowValue) {
                currentMax = prices[i]-lowValue;
            }
            lowValue = Math.min(lowValue,prices[i]);
            maxProfit = Math.max(currentMax,maxProfit);
        }

5. 122买卖股票的最佳时机2

题目描述:
给你一个整数数组 prices ,其中 prices[i] 表示某支股票第 i 天的价格。

在每一天,你可以决定是否购买和/或出售股票。你在任何时候 最多 只能持有 一股 股票。你也可以先购买,然后在 同一天 出售。

返回 你能获得的 最大 利润 。

链接

思路:
第一想到的就是贪心,如果今天有利润,就出售

        int maxProfit =  0;
        for (int i = 1; i < prices.length; i++) {
            if (prices[i]>prices[i-1]){
                //如果今天有利润,就出售
                maxProfit += prices[i]-prices[i-1];
            }
        }

动态规划看题解吧 有点懒得写了。。。

标签:乘积,nums,day6,int,leecode,values,数组,prices
From: https://www.cnblogs.com/Dumbo/p/17303989.html

相关文章

  • flask-day6——sqlalchemy快速插入数据、scoped_session线程安全、sqlalchemy基本增删
    目录一、sqlalchemy快速插入数据二、scoped_session线程安全2.1基本使用2.2加在类上的装饰器三、基本增删查改3.1基本增删查改和高级查询3.2原生sql3.3django中执行原生sql四、一对多4.1表模型4.2新增和基于对象的查询五、多对多5.1表模型5.2增加和基于对象的跨表查询六......
  • 20230409-Python-字符串-day6
    字符串4月9字符串是python中最常见的数据类型,我们可以使用单引号''、双引号""、三引号""""""来创建字符串,只要为变量分配一个值即可#单引号var1='helloword'#双引号var2="helloPython"#三引号,可以换行,如果没有变量名,这就是一个多行注释var......
  • 【LeeCode】523.连续的子数组和
    【题目描述】给你一个整数数组 nums 和一个整数 k ,编写一个函数来判断该数组是否含有同时满足下述条件的连续子数组:子数组大小 至少为2 ,且子数组元素总和为 k 的倍数。如果存在,返回 true ;否则,返回 false 。如果存在一个整数 n ,令整数 x 符合 x=n*k ,则称 x......
  • 【LeeCode】2399. 检查相同字母间的距离
    【题目描述】给你一个下标从 0 开始的字符串 s ,该字符串仅由小写英文字母组成,s 中的每个字母都 恰好 出现 两次 。另给你一个下标从 0 开始、长度为 26 的的整数数组 distance 。字母表中的每个字母按从 0 到 25 依次编号(即,'a'->0, 'b'->1, 'c'->2,.........
  • 【LeeCode】162. 寻找峰值
    【题目描述】峰值元素是指其值严格大于左右相邻值的元素。给你一个整数数组 nums,找到峰值元素并返回其索引。数组可能包含多个峰值,在这种情况下,返回 任何一个峰值 所在位置即可。你可以假设 nums[-1]=nums[n]=-∞ 。你必须实现时间复杂度为 O(logn) 的算法来解决此问题......
  • 【LeeCode】441. 排列硬币
    【题目描述】你总共有 n 枚硬币,并计划将它们按阶梯状排列。对于一个由 k 行组成的阶梯,其第 i 行必须正好有 i 枚硬币。阶梯的最后一行 可能 是不完整的。给你一个数字 n ,计算并返回可形成 完整阶梯行 的总行数。https://leetcode.cn/problems/arranging-coins/【示例......
  • 【LeeCode】2427. 公因子的数目
    【题目描述】给你两个正整数 a 和 b ,返回 a 和 b 的 公 因子的数目。如果 x 可以同时整除 a 和 b ,则认为 x 是 a 和 b 的一个 公因子 。 https://leetcode.cn/problems/number-of-common-factors/【示例】【代码】adminpackagecom.company;//2023-04-0......
  • day6
    1、654最大二叉树递归法构造树一般采用的是前序遍历,因为先构造中间节点,然后递归构造左子树和右子树。递归三部曲确定递归函数的参数和返回值参数传入的是存放元素的数组,返回该数组构造的二叉树的头结点,返回类型是指向节点的指针。确定终止条件确定单层递归的逻辑......
  • python基础:split、join、replace、remove、del、pop、index小记python 字符串的split(
    这里总结了平时写脚本时经常用到的一些基础方法,做个记录1、split()函数可以基于分隔符将字符串分割成由若干子串组成的列表str.split(str="",num=string.count(str))str......
  • 【LeeCode】557. 反转字符串中的单词 III
    【题目描述】给定一个字符串 s ,你需要反转字符串中每个单词的字符顺序,同时仍保留空格和单词的初始顺序。【示例】【代码】adminpackagecom.company;//2023-03-23impo......