今天又看到一条让人忍不住笑出声的吐槽。
话说有家公司要求全员降薪20%,老板喊得激动,全员“共渡难关”。高层也带头降薪,给大家树立了榜样,降了35%。
我想这时候很多员工肯定在心里都想:“哎呦,老板挺慷慨,居然带头降薪。”可谁知道,后面还有大戏呢。
据说,财务部门的某位“敢言”同事透露,啥降薪,完全是个幌子!高层的那部分少拿的钱,最后全都补到年终奖里了。
也就是说,他们降薪只是形式,年终奖一发,全额拿回来了!这就让人好奇了,员工的钱去哪儿了?大部分的降薪,恐怕得“分账”了吧!😂
结果呢,公司里一群人都傻眼了,“我给你降薪,你给我耍心眼”。很多员工一气之下选择了离职,毕竟谁愿意把自己的汗水白白奉献,还被人这么戏耍呢?
这,降薪能接受,但你不能告诉我这是为了我好,最后却是高管拿回了所有的钱。
良心都不会痛吗?
算法题:连续数组
今天我们来聊一个很经典的算法题:连续数组。
听起来好像挺简单的对吧?但其实,这个问题虽然很基础,但却是考察我们对数组、动态规划、哈希表等多种技术的理解和应用。作为程序员,解这种题目其实就是一种磨练我们逻辑思维的方式。
首先,题目要求我们找到给定数组中最大的连续子数组之和。你可以把这个问题理解为:给你一个整数数组,你要找到一个连续的子数组,使得这个子数组的和最大。乍一看,这个问题确实挺简单的,但要高效地解决它,还得动点脑筋。
首先,我们来回顾一下最简单的暴力解法。所谓暴力解法,就是我们直接用两层循环,枚举所有的子数组,然后计算它们的和,找到最大的和。假设数组的长度为n,那么暴力解法的时间复杂度是O(n²)。这种解法不算高效,但它确实能保证我们找到正确的答案。代码长这样:
public class Solution {
public int maxSubArray(int[] nums) {
int maxSum = Integer.MIN_VALUE;
for (int i = 0; i < nums.length; i++) {
int currentSum = 0;
for (int j = i; j < nums.length; j++) {
currentSum += nums[j];
maxSum = Math.max(maxSum, currentSum);
}
}
return maxSum;
}
}
虽然这段代码能够正确地解决问题,但是效率不高。对于一些大的数组来说,可能会非常慢。那么,怎么优化呢?这就引出了一个非常重要的概念——动态规划。
动态规划的核心思想就是将一个大问题拆解成若干个小问题,并通过记录中间结果来避免重复计算。对于这个题目,我们可以通过动态规划来优化。实际上,这个问题可以转化为“当前子数组和是最大值时,前一个元素的子数组和是什么”。我们用dp[i]
来表示以nums[i]
结尾的最大子数组和。
我们可以根据这样的递推关系来构建我们的动态规划解法:
public class Solution {
public int maxSubArray(int[] nums) {
int currentSum = nums[0]; // 第一个元素的最大和就是它本身
int maxSum = nums[0]; // 初始化最大和为第一个元素
for (int i = 1; i < nums.length; i++) {
// 如果当前的和大于0,那么就加上当前元素,否则从当前元素重新开始
currentSum = Math.max(nums[i], currentSum + nums[i]);
maxSum = Math.max(maxSum, currentSum); // 更新最大和
}
return maxSum;
}
}
在这个动态规划解法中,我们只用到了常数的额外空间,因此它的空间复杂度是O(1)。时间复杂度仍然是O(n),这比暴力解法的O(n²)要高效得多。通过这种方式,我们能以较低的复杂度快速求解问题。
但是,问题还没有结束。有些朋友可能会问:“有没有更快的解法?”嗯,其实在某些情况下,我们还可以利用一个非常有意思的技巧,使用哈希表来进一步优化,但这个技巧并不是很常见,通常只有在一些特殊条件下才会使用。在我们现在的这个问题里,动态规划已经足够高效了。
不过,话说回来,很多人解题时总是会犯一些常见的错误。比如在实现动态规划时,可能会忽略初始值设置,导致程序出错。比如上面这段代码,你可能看到currentSum
和maxSum
都初始化为nums[0]
,这其实是一个非常关键的地方。如果初始化错误,程序就会出问题。
再比如,有些小伙伴会直接用dp[i]
来记录每一个子数组的和,虽然这样是正确的,但是它会占用额外的空间。如果你的数组很大,空间消耗也会比较大。所以,像我们这样优化成常数空间的解法会更加高效。
好了,今天就说到这儿,赶紧去刷题吧,解决这个问题之后,肯定能收获不少成就感!记得多想几种解法,不然到面试时,你可能会遇到一个“挑战者”级别的题目。
-END-
以上,就是今天的分享了,看完文章记得右下角给何老师点赞,也欢迎在评论区写下你的留言。