1.差分的基本概念:
如果有一数列 a[1],a[2],.…a[n] 且令 b[i]=a[i]-a[i-1],b[1]=a[1] 那么就有 a[i]=b[1]+b[2]+.…+b[i] =a[1]+a[2]-a[1]+a[3]-a[2]+.…+a[i]-a[i-1] 此时b数组称作a数组的差分数组 换句话来说a数组就是b数组的前缀和数组 例: 原始数组a:9 3 6 2 6 8 差分数组b:9 -6 3 -4 4 2 可以看到a数组是b的前缀和
那么现在有一个任务:
在区间[left,right]上加一个常数c。
我们可以利用原数组就是差分数组的前缀和这个特性,来解决这个问题。显然可得出公式:b[left]+=c,b[right+1]−=c
同样如果通过以上问题让求某一区间的和,那么前缀和也同样能够完成,但是如果操作的次数过大
那么前缀和显然会超时,但是同样有解决的方式例如 树状数组,线段树。
相对于代码长度而言,使用差分的思想求解会变得异常简单。
1.1.1 代表题目:1094. 拼车
public boolean carPooling(int[][] trips, int capacity) { int N = 1010, maxId = 0; int[] diff = new int[N]; int[] cap = new int[N]; for (int[] t : trips) { maxId = Math.max(maxId, t[1]); diff[t[1]] += t[0]; diff[t[2]] -= t[0]; } if (diff[0] > capacity) return false; cap[0] = diff[0]; for (int i = 1; i <= maxId; i++) { cap[i] = cap[i - 1] + diff[i]; if (cap[i] > capacity) return false; } return true; }
买卖股票的最佳时机 II
方法一:动态规划
public class MaxStockProfit { public static int maxProfit(int[] prices) { int len = prices.length; int[][] dp = new int[len][2]; dp[0][0] = 0; dp[0][1] = -prices[0]; for(int i=1; i<len; i++){ dp[i][0] = Math.max(dp[i-1][0], dp[i-1][1] + prices[i]); dp[i][1] = Math.max(dp[i-1][1], dp[i-1][0] - prices[i]); } return dp[len-1][0]; } public static int maxProfit2(int[] prices) { int len = prices.length; int dp0 = 0; int dp1 = -prices[0]; for(int i=1; i<len; i++){ dp0 = Math.max(dp0, dp1 + prices[i]); dp1 = Math.max(dp1, dp0 - prices[i]); } return dp0; } public static void main(String[] args) { int[] prices = {7,1,5,3,6}; System.out.println(maxProfit(prices)); System.out.println(maxProfit2(prices)); } }
方法二:贪心
public static int maxProfit3(int[] prices) {
int len = prices.length;
int ans = 0;
for(int i=1; i<len; i++){
ans += Math.max(0, prices[i] - prices[i-1]);
}
return ans;
}
标签:前缀,int,差分,数组,prices,diff 来源: https://www.cnblogs.com/yuluoxingkong/p/15459530.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。