array专题7

714 Best Time to Buy and Sell Stock with Transaction Fee

思路

首先是暴力枚举。考虑在第idx天能做的操作:买?卖?不操作?

/*** 暴力枚举* * @param prices* @param fee* @return*/public int maxProfitV99(int[] prices, int fee) {return dfs(prices, 0, 0, fee, 0);}/**** 考虑在第idx天是买?卖?不操作?**/private int dfs(int[] prices, int idx, int buyed, int fee, int profit) {if (idx >= prices.length) {return profit;}int max = Integer.MIN_VALUE;if (buyed == 0) {// 买max = Math.max(max, dfs(prices, idx + 1, 1, fee, profit - prices[idx]));} else {// 卖max = Math.max(max, dfs(prices, idx + 1, 0, fee, profit + prices[idx] - fee));}// 不操作max = Math.max(max, dfs(prices, idx + 1, buyed, fee, profit));return max;}

接着:用动态规划的思路来解决

关键是找到递归方程。定义:hold[i]是在第i天持有股票的状态下的最大收益;sold[i]是在第i天卖掉股票的状态下的最大收益; 方程式:hold[i] = Math.max(hold[i-1],sold[i-1]-prices[i])//第i-1天就持有股票,或者第i天购买股票。sold[i] = Math.max(hold[i-1]+prices[i]-fee,sold[i-1])。大家能看到上面的暴力搜索的思路并不完全浪费。在找递归方程中起了作用:hold[i]的计算可能是前一天已经hold,或者是前一天卖了,今天买入。sold[i]的计算可能是前一天已经hold今天卖,或者是前一天已经sold。初始化:hold[0] = -prices[0];sold[0] = 0。

public int maxProfit(int[] prices, int fee) {int n = prices.length;if(n<2) return 0;int[] hold = new int[prices.length];int[] sold = new int[prices.length];hold[0] = -prices[0];sold[0] = 0;for(int i=1;i<prices.length;i++){hold[i] = Math.max(hold[i-1],sold[i-1]-prices[i]);sold[i] = Math.max(hold[i-1]+prices[i]-fee,sold[i-1]);}return Math.max(hold[n-1], sold[n-1]);}

还可以用贪心

关键是选择一个能不能卖掉股票的点,重新开始寻找买入机会。例如序列 1 3 2 8 ,如果发现2<3,就完成交易买1卖3,此时,由于fee=2,那么收益=(3-1-fee)+(8-2-fee) < (8-1-fee),说明卖早了。令maxP是当前最大的price,当(maxP-prices[i]>=fee),时则可以在maxP处卖出,且不会存在早卖的情况。
证明:不明白。

public int maxProfitV3(int[] prices, int fee) {int n = prices.length;if (n < 2)return 0;int maxP = prices[0];int minP = prices[0];int curProfit = 0;int profit = 0;for (int i = 1; i < prices.length; i++) {maxP = Math.max(maxP, prices[i]);minP = Math.min(minP, prices[i]);curProfit = Math.max(curProfit, prices[i] - minP - fee);if(maxP - prices[i]>=fee){profit += curProfit;//在maxP处交易maxP = prices[i];minP = prices[i];curProfit = 0 ;}}return profit+curProfit;}

代码

376 Wiggle Subsequence

思路:用贪心或者动态规划可以解决。
代码

84 Largest Rectangle in Histogram

思路:首先是暴力枚举。 枚举矩形的左右边界。
学习:接着还是暴力枚举,只是这次枚举的是矩形的最低高度。对于一个heights[i],算一下能够到达的最左边的下标和最右边的下标。复杂度还是没降低。在这次枚举过程中会发现可以执行跳跃,省掉一些计算。例如找左边最远:如果当前设置变量j = i;如果heights[i]<=heights[j-1],那直接跳到left[j+1];j=left[j-1],循环再继续判断。例如找右边最远:如果当前设置变量j = i;如果heights[i]<=heights[j+1],那直接跳到right[j+1];j=right[j+1],循环再继续判断。这种跳跃的思想,是学习到的。
代码

621 Task Scheduler

思路:每次应该选择符合条件的剩余总数多的那个任务。符合条件是指符合间隔条件。需要一个map,计算每个任务的数量;需要第二个map,记录当前状态下还有多少个时间间隔。就形成了第一版本的代码。在这个过程中,我没有考虑n=0,没有考虑 每个任务数量不同的情况。是后来才加上的代码。当然代码是超时的。
学习:计算每个不同任务的数量。每次小循环i从1到n,优先选择数量多的不同任务。这里很关键的地方是:只与不同任务的数量有关系,而与任务名称没有关系。用一个一个的数字表示不同的任务。这是我之前一直转不过弯的地方。例如 3个A 1个B 1个C 1个D 1个E ,n=2,最好的顺序是A->B->C->A->D->E->A。第一个小循环用数字表示就是 3-1,1-1,1-1;第二个小循环用数字表示就是2-1,1-1,1-1,第3个小循环是:1-1,因为数组为空,退出。
该思路的难点是处理小循环,注意小循环退出的条件。该思路可以用数组、优先队列两种方法实现。
代码

斐波那契数列

斐波那契数列的计算可以用动态规划计算,也可以用矩阵计算,有O(logn)O(logn)的时间复杂度。
算法去冗余有两种角度:时间冗余和空间冗余。去时间冗余,就是利用空间,将本次计算结果存下来,下次用的时候直接取。F(n)=F(n1)+F(n2)F(n)=F(n−1)+F(n−2),在这个式子中就有重复计算,可以用数组f[i]保存是i时候的结果。空间冗余,就看本次计算相关因素,只需要记录相关因素。还是F(n)=F(n1)+F(n2)F(n)=F(n−1)+F(n−2),不需要记录f[0],f[1],只需要记录f[n-1],f[n-2],两个变量就可以。
动态规划时间复杂度:状态个数*(每个状态计算的时间复杂度);空间复杂度:数组大小。
动态规划解题套路:
1 设计暴力算法,找到冗余;
2 设计并存储状态(一维、二维、三维数组)
3 递归式(状态转移方程)
4 自底向上计算

48 Rotate Image

思路:不多写了。感叹一下自己没想到可以通过多个步骤得到旋转后的矩阵。
代码

153 Find Minimum in Rotated Sorted Array

学习:主要还是要观察所求值的特征。自己总结特征。最小元素的特点有两个:1 如果是旋转元素,那么nums[min]<nums[min1]nums[min]<nums[min−1];2 如果不是旋转元素,那么它应该是nums[0]。所以可以使用二分查找法:如果nums[mid]<nums[mid1]nums[mid]<nums[mid−1],则就是最小元素;否则如果nums[mid]>nums[start] && nums[mid]>nums[end]nums[mid]>nums[start] && nums[mid]>nums[end],那最小元素在右侧;否则在左侧。
代码

560 Subarray Sum Equals K

思路:最近看了动态规划的视频,知道一言不合就暴力搜索。子数组,那可能的枚举就是从0到1,2,3,….从1到2,3,…..。计算这些子数组的和是不是等于k。不过我遇到的几个问题是:1,开始是用递归写的,出现栈溢出,用循环解决。2 没有考虑负数的情况,在sum>=k的时候就break。3 没有考虑[0,0,0,0,0] 这种情况,在以i为开始,找到和为k的情况就break。时间复杂度O(n2n2)。
学习:子数组的和就是指从[i,j]的和。sum[i,j] = sum[0,j]-sum[0,i-1]。
代码

795 Number of Subarrays with Bounded Maximum

思路:分析题意要求每个子数组的最大值maxVal必须满足maxVal>=LmaxVal>=L and maxVal<=RmaxVal<=RmaxVal<=RmaxVal<=R可以推出子数组中每个元素<=R<=R<script type="math/tex" id="MathJax-Element-11"><=R</script>。
子数组的暴力枚举:以i为起始,可以行程[i][i,i+1],[i,i+2]….[i,n-1]个子数组。在枚举子数组的时候把不符合条件的去掉,计数有效子数组即可。时间复杂度O(n^2)。
学习:改为O(n)。为什么不是O(nlogn)。因为一般logn需要有二分,而二分一般涉及到排序。本题是不能排序的。所以应该是O(n)。要想O(n)就应该是一个一个元素遍历,或者根据需要多遍历几次。
遍历每个元素i,会发现,如果A[i]>=LA[i]<=RA[i]>=L并且A[i]<=R
数组[2,1,4,3] L=2,R=3
下标0:A[i]>=LA[i]<=RA[i]>=L并且A[i]<=R 增加个数1
下标1:A[i]<LA[i]<L 自己不能单独成为子数组,可以追加在前面的子数组后面。所以前面有几个子数组这里就增加几。
下标2:A[i]>RA[i]>R 不增加
下标3:A[i]>=LA[i]<=RA[i]>=L并且A[i]<=R,增加1个。因为前一个元素超出范围了,只能从下标3开始计算。
代码

162 Find Peak Element

思路:找极值点。之前在贪心里面有一道题比这个还要难。思路就是找到一个元素i 如果 (nums[i]-nums[i-1])*(nums[i+1]-nums[i])<0,就找到了极值点的下标i。
学习:二分查找。这道题目居然也可以用二分。一直以为不排序的数组没法用二分查找。原因是这样的。只要找到一个极值点即可。在达到极值点前或者过了极值点之后是有序的。
ifnums[i1]<nums[i]<nums[i+1]ifnums[i−1]<nums[i]<nums[i+1],那么极值点一定在i+1,i+2…n-1中。
ifnums[i1]>nums[i]>nums[i+1]ifnums[i−1]>nums[i]>nums[i+1],那么极值点一定在[0,1,…i-1]中
ifnums[i1]<nums[i]>nums[i+1]ifnums[i−1]<nums[i]>nums[i+1],那么极值点就是i
所以学习到局部有序,也可以用二分查找。
代码

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/424799.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

第三十九期:收藏 | 第一次有人把“分布式事务”讲的这么简单明了

不知道你是否遇到过这样的情况&#xff0c;去小卖铺买东西&#xff0c;付了钱&#xff0c;但是店主因为处理了一些其他事&#xff0c;居然忘记你付了钱&#xff0c;又叫你重新付。 作者&#xff1a;咖啡拿铁来源 又或者在网上购物明明已经扣款&#xff0c;但是却告诉我没有发…

【小技巧】字符char与整型int的相互转换

char转int char与int的相互转化&#xff0c;联想ASCII码&#xff0c;字符‘0’对应的值为48&#xff0c;所以不能直接加减‘ ’ char ch9; int ch_intch-0;//此时ch_int9int转char int i9&#xff1b; char i_chi0;//此时i_ch9必须牢记的ASCII

array专题8

670 Maximum Swap 思路&#xff1a;先把整数分解成一个一个的数&#xff0c;从0-n放着从最低位到最高位的数字。例如2376变成数组[6,7,3,2]。假设要替换的是最高位n-1,从0到n-2中查找是否有比nums[n-1]大的元素&#xff1b;如果有则替换&#xff0c;否则继续考虑替换n-2位。比…

nginx 编译安装

安装 Nginx 所依赖的基本服务&#xff1a; yum -y install gcc gcc-c automake pcre pcre-devel zlip zlib-devel openssl openssl-devel 官网 http://nginx.org 下载安装包 编译nginx make (可参考http://nginx.org/en/docs/configure.html) ./configure --prefix/data1/se…

第四十期:九个对Web开发者最有用的Python包,掌握这些,工资至少能涨涨

Matplotlib&#xff0c;正如其名称所暗示的那样&#xff0c;是一个用来绘制数学函数和模型的库;扩展了Numpy的作用&#xff0c;Matplotlib可以只用几行代码来创建图&#xff0c;条形图&#xff0c;散点图等诸多视觉表现。 作者&#xff1a;Python之眼来源&#xff1a;今日头条…

array专题9

新的一周&#xff0c;新的专题。array的中等难度的题目快要结束了。能感觉到进步&#xff0c;也依然能感觉到吃力。加油。 31 Next Permutation 思路&#xff1a;读懂了题意&#xff0c;知道是要求下一个排列数是什么。如果已经到最后一个了&#xff0c;那就返回最小的那个。…

[Leetcode][第214题][JAVA][最短回文串][KMP][RK]

【问题描述】[中等] 【解答思路】 1. 字符串哈希 复杂度 class Solution {public String shortestPalindrome(String s) {int n s.length();int base 131, mod 1000000007;int left 0, right 0, mul 1;int best -1;for (int i 0; i < n; i) {left (int) (((long)…

坏掉的项链Broken Necklace

题目描述 你有一条由N个红色的&#xff0c;白色的&#xff0c;或蓝色的珠子组成的项链(3<N<350)&#xff0c;珠子是随意安排的。 这里是 n29 的二个例子: 第一和第二个珠子在图片中已经被作记号。 图片 A 中的项链可以用下面的字符串表示&#xff1a; brbrrrbbbrrrrrbrrb…

689 Maximum Sum of 3 Non-Overlapping Subarrays

题目 思路&#xff1a;首先是长度为k的子数组的和。这个好计算。题目要求返回的是三个和最大的子数组的第一个数字的下标。下标要尽可能小。如果只要求这样&#xff0c;题目就很简单了。还有个要求是各个子数组不重叠。要想不重叠首先得要求下标不重叠。子数组1下标是:0,1,2&a…

[Leetcode][第557题][JAVA][反转字符串中的单词 III][遍历][String函数]

【问题描述】[简单] 【解答思路】 1. 遍历 开辟一个新字符串。然后从头到尾遍历原字符串&#xff0c;直到找到空格为止&#xff0c;此时找到了一个单词&#xff0c;并能得到单词的起止位置。随后&#xff0c;根据单词的起止位置&#xff0c;可以将该单词逆序放到新字符串当中…

第七十二期:爬虫爬的好,牢饭吃到饱?

前几天分享的一篇《只因写了一段爬虫&#xff0c;公司200多人被抓!》相信大家看了后都会发问&#xff0c;我只是个写爬虫的&#xff0c;跟我有什么关系?到底什么样的爬虫才不犯法?今天这篇会解答你所有的疑问。 作者&#xff1a;技术领导力 前几天分享的一篇爬虫被抓相信大…

如何在Swift中创建漂亮的iOS图表

通过图形和图表呈现数据是当今移动应用程序最显着的特征之一。iOS图表使应用程序看起来更漂亮&#xff0c;更有吸引力。 在本教程中&#xff0c;我们将向您展示如何使用代码示例在Swift中实现我们的iOS图表。我们将看一下Swift折线图&#xff0c;饼图以及条形图。 您可以找到许…

第七十四期:从bug看11种编程语言演化史,果然如今Python比较流行

在本文中&#xff0c;作者选择了 11 种非常流行的编程语言&#xff08;通过 Stack Overflow 标签出现的频率衡量&#xff09;&#xff0c;希望可以找出这些问题的共性及差异性。 作者&#xff1a;机器之心编译来源&#xff1a;机器之心 自 2008 年创办以来&#xff0c;Stack …

[Leetcode][第841题][JAVA][钥匙和房间][DFS][BFS]

【问题描述】[中等] 【解答思路】 当 xx 号房间中有 yy 号房间的钥匙时&#xff0c;我们就可以从 xx 号房间去往 yy 号房间。如果我们将这 nn 个房间看成有向图中的 nn 个节点&#xff0c;那么上述关系就可以看作是图中的 xx 号点到 yy 号点的一条有向边。 这样一来&#xff…

LinkedList专题1

237 Delete Node in a Linked List 思路&#xff1a;单向链表&#xff0c;只给定要删除的节点。怎么删除这个节点。参考。例如要删除节点node。一般来说我们需要将node.preNode.next node.next。但是现在没有node的上一个节点。代替方案是修改当前节点为node.next节点。 node…

死磕 java同步系列之开篇

简介 同步系列&#xff0c;这是彤哥想了好久的名字&#xff0c;本来是准备写锁相关的内容&#xff0c;但是java中的CountDownLatch、Semaphore、CyclicBarrier这些类又不属于锁&#xff0c;它们和锁又有很多共同点&#xff0c;都是为了协同多线程的执行&#xff0c;都是一种同步…

第七十五期:Java 2019 生态圈使用报告,这结果你赞同吗?

这是国外一机构调查了 7000 名开发者得出来的 Java 2019 年生态圈工具使用报告&#xff0c;主要调查了 Java 版本、开发框架、web 服务器等使用情况。 作者&#xff1a;平头哥来源 这是国外一机构调查了 7000 名开发者得出来的 Java 2019 年生态圈工具使用报告&#xff0c;主…

[Leetcode][第486题][JAVA][预测赢家][动态规划][递归]

【问题描述】[中等] 【解答思路】 1.递归 复杂度 class Solution {public boolean PredictTheWinner(int[] nums) {return total(nums,0,nums.length-1,1) >0;}//turn 标记轮到谁了 正数表示先手 负数表示后手 public int total( int[]nums ,int start,int end,int tur…

linux-2.6.38 input子系统(用输入子系统实现按键操作)

一、设备驱动程序 在上一篇随笔中已经分析&#xff0c;linux输入子系统分为设备驱动层、核心层和事件层。要利用linux内核中自带的输入子系统实现一个某个设备的操作&#xff0c;我们一般只需要完成驱动层的程序即可&#xff0c;核心层和事件层内核已经帮我们做好了。因此这篇随…

LinkedList专题2

203 Remove Linked List Elements 思路&#xff1a;考虑1 &#xff1a; 可能有多个节点符合&#xff1b;考虑2&#xff1a;命中节点是head&#xff1b;考虑3&#xff1a;命中节点是尾节点&#xff1b;考虑4&#xff1a;命中节点是中间的普通节点。 学习1&#xff1a;在linked…