下岗年纪从35降到30,现在降到28了。。。
最近在网上看到一个挺有意思的吐槽,感觉还蛮有共鸣的——网友说:下岗的年纪从35岁降到30岁,现在又降到28岁了。
想想也有点唏嘘,尤其对于我们程序员来说,30岁可能是个很尴尬的分水岭。
可实际上,尤其是做技术的,我们的焦虑从来不晚——30岁之后,你不仅要拼技术能力,更得拼经验、拼项目、拼"软技能"。
我觉得,35岁、30岁、28岁这些界限,真不全是年龄的数字,而是行业的标签。每一段时间你都在感受自己从新鲜血液变成了“成熟”技术员的过程,而这种过程有时候很不容易。我们这一行,技术更新换代的速度快,年轻人聪明能干,感觉好像35岁、30岁就成了不受欢迎的“古董”。🤔
做程序员的,技术上不拼的只是拖慢了脚步,其他的方面同样可以发力。对吧?【备注:文末可领最新资料】。
算法题:使序列递增的最小交换次数
首先,题目描述大概是这样的:给定一个无序的整数序列,你需要通过交换元素的方式,让整个序列变得递增。目标是通过最少的交换次数达到这个目的。
我们先从一个简单的思路出发来理解这个问题。首先,递增序列的定义就是每个元素都比前一个元素大,所以我们需要找到当前序列中每个数字应该处于的位置,并将它们交换过去。
看起来,应该可以通过“排序”来解决问题。你也许会说:“咦,既然要递增排序,那我们直接用快排或者归并排序不就好了?”。但是我们要注意题目的要求:最小交换次数!使用传统的排序算法虽然能排好序,但是交换次数却不一定最少。所以,怎么确保交换最少呢?
为了找到最小交换次数,我们其实可以用一种思路,跟图论中“环”的思想有点相似。
假设我们把原始数组中的每个元素都映射到它应该在递增排序中对应的位置,然后我们就得到了一个“图”——每个数字的当前位置和它应该在的目标位置之间会形成一个连接。通过这种方式,我们可以把数组中的交换问题转换为环的重排问题。
来个简单的例子:
原始数组:[4, 3, 2, 1]
排序后:[1, 2, 3, 4]
首先我们想一下,如何通过交换让这个数组变成递增的。最直接的思路就是首先看第一个位置的元素4,它应该在排序后的最后位置,所以我们要把它和4所在位置的元素交换。接着,剩下的元素继续按照这个思路操作,直到所有元素都在正确的位置。
这个思路的核心在于每个元素都形成了一个“环”。比如说,4应该去的位置是1的位置,1应该去的位置是4的位置,依此类推,最终每个元素都通过交换被放到了它该去的地方。每个环中的元素只需要进行循环交换一次,就可以把它们放到正确的位置。
接下来,我们写个简单的Java代码,来实现这个思想:
public class MinSwaps { public static int minSwaps(int[] arr) {
int n = arr.length;
// 复制数组并排序
int[] sortedArr = arr.clone();
Arrays.sort(sortedArr);
// 用来存储每个元素的索引
HashMap<Integer, Integer> indexMap = new HashMap<>();
for (int i = 0; i < n; i++) {
indexMap.put(sortedArr[i], i);
}
// 标记是否已经访问过
boolean[] visited = new boolean[n];
int swaps = 0;
// 遍历数组
for (int i = 0; i < n; i++) {
// 如果已经访问过或者已经在正确位置,跳过
if (visited[i] || arr[i] == sortedArr[i]) {
continue;
}
// 计算环的大小
int cycleSize = 0;
int j = i;
while (!visited[j]) {
visited[j] = true;
j = indexMap.get(arr[j]);
cycleSize++;
}
// 如果环的大小大于1,则需要交换cycleSize - 1次
if (cycleSize > 1) {
swaps += cycleSize - 1;
}
}
return swaps;
}
public static void main(String[] args) {
int[] arr = {4, 3, 2, 1};
System.out.println("最小交换次数: " + minSwaps(arr)); // 输出最小交换次数
}
}
在这段代码中,我们首先创建了一个新的数组 sortedArr,并对它进行了排序。接着,我们构建了一个 indexMap,用来存储每个元素在排序后数组中的索引。然后,我们遍历原始数组,如果某个元素已经在正确的位置,或者已经访问过,就跳过它。否则,我们就开始找到这个元素形成的环,直到该环中的所有元素都被访问过为止。最后,环的大小减1,就是我们需要交换的次数。
假设我们用这个代码来解决 arr = {4, 3, 2, 1} 的问题,最终输出的最小交换次数是3,正好与我们的预期一致。
通过这个方式,我们就能在最小交换次数内将数组排序了。其实这种思路也类似于图论中的“连通分量”问题,利用环来减少不必要的交换次数。想想看,每次交换其实都像是在拼图,每个环内的元素只需要互相调换位置,就能顺利归位了。
当然,这道题的实现虽然挺简单,但背后隐藏的思维却不容小觑。如果能理解这其中的“环”结构,感觉一下子就打开了另一种思考方式——把复杂问题化繁为简。
-END-
以上,就是今天的分享了,看完文章记得右下角给何老师点赞,也欢迎在评论区写下你的留言。