当前位置: 首页 > news >正文

通州重庆网站建设西安网站建设公司排行榜

通州重庆网站建设,西安网站建设公司排行榜,产品推广方案范本3篇,bluehost网站后台K 次取反后最大化的数组和 题目详细:LeetCode.1005 这道题比较简单,这里直接给出贪心策略: 局部最优解: 按照 负数 > 0 > 正数 的优先级次序,依次对nums中的较小数值进行取反因为负负得正,负值越小…

K 次取反后最大化的数组和

题目详细:LeetCode.1005

这道题比较简单,这里直接给出贪心策略:

  • 局部最优解:
    • 按照 负数 > 0 > 正数 的优先级次序,依次对nums中的较小数值进行取反
    • 因为负负得正,负值越小,其相反数越大
    • 如果值都为正数,那么则取较小的值进行取反,尽可能的最大化数组和
  • 整体最优解:整体的数组和最大

Java解法(贪心,数组有序):

class Solution {public int largestSumAfterKNegations(int[] nums, int k) {// 对原数组进行排序Arrays.sort(nums);// 优先对负数进行取反int i = 0;while(k-- > 0){// 当遇到正数时,说明其上一个数肯定也是非负数// 需要比较两个值的大小,让数值较小的值取反if(i > 0 && nums[i] > nums[i - 1]){i--;}// 取反nums[i] = 0 - nums[i];// 边界判断if(++i >= nums.length)i = nums.length - 1;}// 累计数组总和int sum = 0;for(int n: nums){sum += n;}return sum;}
}

当然由于LeetCode给出的数据样本,范围较小且保证样本数组都落在一定范围内,我们也可以利用数组下标来映射nums中的数值,使数值在映射数组中得到有序,就不用Arrays.sort方法了。

Java解法(贪心,数组不有序):

class Solution {public int largestSumAfterKNegations(int[] nums, int k) {// 样本数据都满足,-100 <= nums[i] <= 100,这个范围的大小是201int[] number = new int[201];// 数组下标[-100,100]表示数值大小,元素值表示数值的个数for (int t : nums) {// 利用 t + 100 将[-100,100]映射到[0,200]上number[t + 100]++;}int i = 0;while (k-- > 0) {// 跳过记录次数为0的数字,找到当前nums中最小的数字while (number[i] == 0){i++;}// 若 i > 100,说明索引到了正数if (i > 100) {if(k % 2 == 0){// 正数取偶数次反,依旧是正数,直接break跳出循环;break;}// 正数取奇数次反,一定是负数,直接k = 0,后续执行一次数值取反就行k = 0;}// 取反number[i]--;// 该数字的个数 - 1number[200 - i]++;// 该数字的相反数个数 + 1}// 累计数字个数求和int sum = 0;for (int j = 0; j < number.length ; j++) {// j - 100 是数字的大小,number[j]是该数字出现次数.sum += (j - 100)* number[j];}return sum;}
}

加油站

题目详细:LeetCode.134

这道题一开始我的思路是比较正确的:

  • 假如我们从某一个加油站开始,那么这个加油站之前和之后的路段都是它要行驶的路段
  • 所以判断能否行驶一周,那么只需要累计每一段路程的差值,如果差值不为负,说明能够行驶一周,否则无法行驶一周,返回 -1
  • 那么再根据我的贪心的思想,我计算并记录了每一段路程中,差值为正且最大的加油站开始,觉得这样就可以满足后续的路程
  • 最后根据累计值,判断能否行驶一周,如果可以则返回记录的下标

但是经过测试后,发现还是会有错误的数据样本,看完题解之后,才发现我的思路是比较片面的,主要的原因在于确定起始坐标上犯了迷糊,若当前的累计值cur_sum < 0,起始位置至少要是i+1,而不是i

所以正确的贪心策略应该是:

  • 局部最优解:
    • 当前累加rest[i]的和cur_sum < 0时,起始位置start_index至少要更新到i+1
    • 因为假如从i之前开始,那么它走到第i个时,必定是cur_sum < 0,就无法继续行驶了
  • 整体最优解:找到可以跑一圈的起始位置start_index,如果最后所有油耗的累计值 < 0,说明车辆不足油跑一圈,返回 -1

这里我定义了一个变量min_sum,来记录路程中差值最大的油耗,只要当cur_sum < min_sum时,就需要更新start_index = i + 1

Java解法(贪心):

class Solution {public int canCompleteCircuit(int[] gas, int[] cost) {int n = gas.length, start_index = 0, cur_sum = 0, min_sum = 0;for(int i = 0; i < n; i++){cur_sum += gas[i] - cost[i];if(cur_sum < min_sum){start_index = i + 1;min_sum = cur_sum;}}return cur_sum < 0 ? -1 : start_index;}
}

如果起始位置的更新条件为cur_sum < 0时,则需要更新cur_sum = 0,这是意义更加明确的解法,表示从车辆从当前加油站开始,其之前的加油站都还未经过,所以不需要累计油耗,重置cur_sum = 0,后续再累计油耗;

不过就需要定义一个变量total_sum,通过该变量来判断是否能够绕行一圈了。

Java解法(贪心):

class Solution {public int canCompleteCircuit(int[] gas, int[] cost) {int n = gas.length, start_index = 0, cur_sum = 0, total_sum = 0;for(int i = 0; i < n; i++){cur_sum += gas[i] - cost[i];total_sum += gas[i] - cost[i];if(cur_sum < 0){start_index = i + 1;cur_sum = 0;}}return total_sum < 0 ? -1 : start_index;}
}

分发糖果

题目详细:LeetCode.135

我一开始的分发策略是:

  • 第一次是从左到右遍历,比较左边孩子和右边孩子的评分,如果左边孩子比右边孩子的评分高,那么左边孩子的糖果数量 = 右边孩子的糖果数量 + 1(第一次遍历,这样变成了左边孩子的糖果数量由右边孩子决定,但是右边孩子的糖果数量还未确定,进而在这一步就确定左边孩子的糖果数量是错误的)。
  • 第二次是从右到左遍历,比较右边孩子和左边孩子的评分,如果右边孩子比左边孩子的评分高,那么右边孩子的糖果数量 = max(右边孩子的糖果数量,左边孩子的糖果数量 + 1)(第二次遍历,右边孩子的糖果数量由左边孩子决定,但是由于第一次遍历时,左边孩子的糖果数量就确定错误了,所以第二次遍历的结果也是错误的)。

做题的时候总觉得这样的思路没问题呀,怎么老是通过不了一些测试样本呢,看过题解之后才发现括号里那些没有发现的错误,详细的题解可查阅:《代码随想录》— 分发糖果

按我原来的分发策略举个错误的例子,例如:

  • 因为rating[1]与rating[2]的比较,是要利用上rating[2]与rating[3]的比较结果来确定rating[2]的糖果数量,才能进而确定rating[1]的糖果数量
  • 假如从前向后遍历,就无从得知rating[2]与rating[3]的的比较结果了,所以要从后向前遍历。

所以本题正确的分发策略应该是:

  • 局部最优解:
    • 第一次是从左到右遍历,所以右边孩子的糖果数量都能通过左边孩子的糖果数量得到确定(右边孩子的糖果数量 = 左边孩子的糖果数量 + 1),只比较右边孩子比左边孩子的评分高的情况。
    • 第二次是从右到左遍历,所以左边的孩子的糖果数量都能通过右边孩子的糖果数量得到确定(左边孩子的糖果数量 = max(左边孩子的糖果数量,右边孩子的糖果数量 + 1)),只比较左边孩子比右边孩子的评分高的情况,保留孩子的最大的糖果数量。
  • 整体最优解:相邻的孩子中,评分高的孩子获得更多的糖果。
  • 最后累计所有孩子的糖果数量即可得到结果

Java解法(贪心):

class Solution {public int candy(int[] ratings) {int len = ratings.length;int[] candy = new int[len];// 每个孩子至少分得1个糖果Arrays.fill(candy, 1);for(int i = 1; i < len; i++){if(ratings[i] > ratings[i - 1]){candy[i] = candy[i - 1] + 1;}}for(int i = len - 2; i >= 0; i--){if(ratings[i] > ratings[i + 1]){candy[i] = Math.max(candy[i], candy[i + 1] + 1);}}int sum = 0;for(int n: candy){sum += n;}return sum;}
}

http://www.ds6.com.cn/news/99344.html

相关文章:

  • 手机网站用什么做的搜索引擎有哪些技巧
  • 怎么用自己电脑做网站搜索引擎优化自然排名的优点
  • 日ip5000的网站怎么做精准营销的三要素
  • winxp下做网站nba球队排名
  • 开发软件和做网站的区别北京优化靠谱的公司
  • 卡通风格网站欣赏郑州网络优化实力乐云seo
  • 做网站域名起什么作用上海seo优化外包公司
  • 乐清网站只做百度知道合伙人
  • 公司免费网站搭建湖南seo推广软件
  • 网站配置文件在哪里天津百度
  • 微信小程序商城官网杭州网站seo外包
  • workerman 做网站廊坊快速优化排名
  • 网站定制业务营销网站建设免费
  • 四川省建设工程招投标网站整合营销
  • 怎么用VS2012建设网站外链网站是什么
  • com网站域名百度竞价排名什么意思
  • 英雄联盟网站模版网络推广推广
  • 自助商城网站建设seo关键词快速排名软件
  • 创建wordpress主题南阳seo优化
  • 做网站需要什么配置服务器推广效果最好的平台
  • 做网站怎么切片网站建设
  • 人才网站 建设好 窗口百度公司排名
  • 做网站一定要买主机吗长沙网站seo方法
  • wordpress rest api评论seo的主要内容
  • 做新得网站可以换到原来得域名嘛百度seo公司兴田德润
  • wordpress iis 伪静态seo网站优化方
  • sae 企业网站职业培训网
  • 网站建设合同注意事项网站运营seo实训总结
  • 北京做微信网站足球世界排名
  • 网站设计与制治疗腰椎间盘突出的特效药