最近面了某外包,真真切切感受到外包公司的恶意。。
最近刷到个程序员吐槽贴,简直让我笑哭了(不是开心那种😂)。某位兄弟去面了一家外包公司,本想着能敲个满意的 offer,结果呢,这家公司花式“整活儿”,仿佛在玩职场版狼人杀。
起初,公司谈好 21k,试用期 3 个月打 8 折。看起来还算勉强能接受,结果还没等小哥点头,公司突然升级难度——变成 21k,试用期延长到 6 个月,依旧打 8 折。小哥心想,这待遇还不如隔壁的工资条香,果断拒绝。
没想到第二天,公司又“花式加码”,试用期 6 个月但涨到 9 折。这个变脸速度,妥妥的川剧传人吧?最后,小哥权衡之后决定先干一两个月,结果公司玩出大招:工资缩水到 19.3k,试用期再打 9 折,还变成了 13 薪!🤣
看得我直呼好家伙,这是真正的“降薪自由”。作为程序员,遇到这种操作,只能说一句:外包的水太深了,能绕路就绕路吧。职场里摸鱼可以接受,但被鱼摸,这可不行!【备注:文末可领最新资料】
算法题:使序列递增的最小交换次数
今天我们来聊一个有意思的算法问题:如何让一个序列递增,同时保证交换次数最少?
事情是这样的,有两个长度相同的序列 A 和 B,我们需要让它们的每一对 (A[i], B[i]) 都递增。你可以选择交换 A[i] 和 B[i],但每次交换是要收费的(虚拟收费,别怕)。目标就是用最少的交换次数,完成这个任务。
举个例子:
A = [1, 3, 5, 4]
B = [1, 2, 3, 7]
你能用最少的交换次数让 (A[i], B[i]) 都递增吗?
解题思路
这个问题看着挺吓人,其实是动态规划的一个变种。动态规划的核心思路是把大问题分解为多个小问题,并记录中间状态。
这里我们定义两个状态:
keep[i]表示到第i位时,如果不交换,最小的交换次数。swap[i]表示到第i位时,如果交换,最小的交换次数。
转移条件
如果
(A[i-1] < A[i] and B[i-1] < B[i]),说明A[i]和B[i]都大于前一对,无需额外调整:
不交换: keep[i] = keep[i-1]交换: swap[i] = swap[i-1] + 1
如果 (A[i-1] < B[i] and B[i-1] < A[i]),说明交叉交换也能满足条件:
不交换: keep[i] = min(keep[i], swap[i-1])交换: swap[i] = min(swap[i], keep[i-1] + 1)
初始状态:
keep[0] = 0(第一个位置不需要交换)swap[0] = 1(第一个位置交换一次)
最后答案是 min(keep[-1], swap[-1])。
Python实现
代码来了!这段代码简单直接,带点注释:
def min_swap(A, B):
n = len(A)
keep = [float('inf')] * n # 不交换的状态
swap = [float('inf')] * n # 交换的状态 # 初始状态
keep[0] = 0
swap[0] = 1
for i in range(1, n):
# 条件1:不需要交换即可递增
if A[i - 1] < A[i] and B[i - 1] < B[i]:
keep[i] = keep[i - 1] # 不交换
swap[i] = swap[i - 1] + 1 # 上一对交换,这一对也交换
# 条件2:需要交叉交换
if A[i - 1] < B[i] and B[i - 1] < A[i]:
keep[i] = min(keep[i], swap[i - 1]) # 上一对交换,这一对不交换
swap[i] = min(swap[i], keep[i - 1] + 1) # 上一对不交换,这一对交换
# 返回最后结果
return min(keep[-1], swap[-1])
测试一下
我们来测试刚才的例子:
A = [1, 3, 5, 4]
B = [1, 2, 3, 7]result = min_swap(A, B)
print("最少交换次数:", result)
运行后会输出:
最少交换次数: 1
不过说实话,动态规划题确实挺烧脑的。每次写完这类题,我都觉得脑子像个CPU,动辄满负荷运行。但是那种看到答案的成就感,真的是无可比拟的。
好了,今天的分享就到这里。如果你有更巧妙的解法,或者觉得我写得有哪里不对劲,记得留言告诉我!
对编程、职场感兴趣的同学,大家可以联系我微信:golang404,拉你进入“程序员交流群”。
虎哥作为一名老码农,整理了全网最全《python高级架构师资料合集》。