外包一个月2万7,不交社保,能去么
今天看到一个网友发帖问:外包一个月2万7,不交社保,能去吗?🤔 说实话,看到这个问题,我的第一反应是——要看清楚,这到底是不是一个“坑”!
作为程序员,大家都知道,外包的薪资看似很高,特别是2万7这个数字,确实诱人,毕竟大部分公司给的工资加上社保也许还没这么高。
可是问题来了——不交社保。这在我看来,绝对是一个大大的警告标志。💥
想想看,社保本来就是国家规定的保障,你不仅是为了医疗、退休积累一笔钱,也是为了防止未来一些突发的情况。
所以我觉得,如果真的是失业在家的情况下,薪资高当然很诱人,但也要考虑清楚长远的影响。
当然也不是完全没有办法,你可以自己购买社保,只是你需要根据自己的情况来做取舍,薪资足够高,自己购买也行
算法题:区间和的个数
今天我想跟大家聊聊一个在面试中常常出现的算法题:区间和的个数。
题目大致是这样的:给定一个数组 nums 和一个目标值 target,我们需要找到所有和为 target 的子数组的个数。啥意思呢?也就是说,你要从这个数组中找出一组子数组,它们的和刚好等于 target。比如对于数组 [1, 1, 1] 和目标值 2,返回的结果应该是 2,因为有两个子数组 [1, 1]。
我觉得这道题虽然看似简单,但其实背后有不少值得我们琢磨的地方。首先是基本思路,如果你直接用暴力方法去解,复杂度会非常高。你得暴力枚举所有的子数组,每个子数组求和,显然这样就会导致时间复杂度达到 O(n^3),如果数组很长,那简直是个灾难。
优化方案
对于这个问题,我们可以通过前缀和的技巧来优化。具体来说,前缀和是一个非常常见的技巧,它的基本思想是:如果你能提前算出数组前面所有元素的和,那么你就能快速地计算出任意区间的和。比如,对于一个数组 nums,前缀和数组 prefix_sum 定义为:prefix_sum[i] = nums[0] + nums[1] + ... + nums[i-1]。这样,任意区间 nums[i...j] 的和就可以通过 prefix_sum[j+1] - prefix_sum[i] 快速求出。
具体到这个问题,我们可以利用一个哈希表来存储已经出现的前缀和,借助哈希表的查询时间复杂度为 O(1) 的特性,我们可以在遍历数组的过程中进行优化。
代码实现
这里是用 Python 写的一个优化版的解决方案:
def subarraySum(nums, target):
# 用一个字典存储前缀和出现的次数
prefix_sum_count = {0: 1} # 默认有一个前缀和为0的情况
current_sum = 0 # 当前的前缀和
result = 0 # 结果变量,存储符合条件的子数组个数 for num in nums:
current_sum += num # 更新当前的前缀和
# 检查当前前缀和减去目标值是否出现在之前的前缀和中
if current_sum - target in prefix_sum_count:
result += prefix_sum_count[current_sum - target]
# 将当前前缀和添加到字典中,记录它出现的次数
if current_sum in prefix_sum_count:
prefix_sum_count[current_sum] += 1
else:
prefix_sum_count[current_sum] = 1
return result
解释一下
我们首先初始化一个字典 prefix_sum_count,用来存储已经计算过的前缀和及其出现的次数。字典的键是前缀和,值是该前缀和出现的次数。为什么要有一个{0: 1}初始值呢?因为如果当前前缀和正好等于目标值target,那么我们就找到了一个子数组,满足条件的个数就增加了 1。current_sum是我们当前遍历到的位置的前缀和。对于每一个元素,我们计算当前的前缀和 current_sum,然后查看current_sum - target是否已经出现在字典中。如果存在,就说明从某个之前的位置到当前位置的子数组和为target,于是就增加结果result。然后,我们更新字典,记录当前的前缀和。
为什么这样做是优化的呢?
暴力解法每次求和都要遍历一遍子数组,时间复杂度高。而这个优化版的解法,利用前缀和来将问题转化为查找问题,查找一个前缀和是否出现过,因此将问题的时间复杂度降低到 O(n)。而字典操作的时间复杂度是 O(1),所以这相对暴力解法而言,性能提升是巨大的。
测试用例
让我们来跑几个测试看看这个算法的效果:
# 测试用例 1
nums = [1, 1, 1]
target = 2
print(subarraySum(nums, target)) # 输出 2# 测试用例 2
nums = [1, 2, 3]
target = 3
print(subarraySum(nums, target)) # 输出 2
# 测试用例 3
nums = [0, 0, 0, 0]
target = 0
print(subarraySum(nums, target)) # 输出 10
对于第一组 [1, 1, 1] 和目标 2,我们会找到两个符合条件的子数组 [1, 1],所以输出是 2。第二组和第三组也分别验证了不同的情况,符合我们的预期。
小结
这道题从表面上看并不复杂,但是需要掌握前缀和的技巧并合理使用哈希表来优化查找操作。通过这种方式,我们将时间复杂度从 O(n^2) 或 O(n^3) 降低到了 O(n),这对于大数据量来说尤为重要。
说到这里,你可能会想:这种优化技巧在其他问题中也能用吧?没错,前缀和和哈希表的组合其实在很多地方都有应用,比如求解连续子数组的和、子数组的最大和等问题,都是很好的思路。
对编程、职场感兴趣的同学,大家可以联系我微信:golang404,拉你进入“程序员交流群”。
虎哥作为一名老码农,整理了全网最全《python高级架构师资料合集》。