用可视化学习逆置法
1.逆置法思路
目标:将这个彩色数组向右旋转3步
🔴1 → 🟠2 → 🟡3 → 🟢4 → 🔵5 → 🟣6 → ⚪7
我们希望得到
🔵5 → 🟣6 → ⚪7 → 🔴1 → 🟠2 → 🟡3 → 🟢4
接下来我们用可视化的方式来描述逆置法的过程。
步骤1:整体大翻转
想象把整个数组完全倒过来排列:
【原始数组】
🔴1 → 🟠2 → 🟡3 → 🟢4 → 🔵5 → 🟣6 → ⚪7【把每个数和它对应的位置互换】
⚪7 ← 🟣6 ← 🔵5 ← 🟢4 ← 🟡3 ← 🟠2 ← 🔴1
步骤2:前三个数字再翻转
现在,只翻转前三个数字(K=3):
【当前数组】
⚪7 → 🟣6 → 🔵5 → 🟢4 → 🟡3 → 🟠2 → 🔴1【把前3个数互换位置】
🔵5 → 🟣6 → ⚪7 → 🟢4 → 🟡3 → 🟠2 → 🔴1
第二步完成:前3个数字排序正确了!
步骤3:剩余的四个数字也翻转
最后,翻转剩下的4个数字:
【当前数组】
🔵5 → 🟣6 → ⚪7 → 🟢4 → 🟡3 → 🟠2 → 🔴1【把后4个数互换位置】
🔵5 → 🟣6 → ⚪7 → 🔴1 → 🟠2 → 🟡3 → 🟢4
第三步完成:所有数字都排序正确了!
最终结果:
🔵5 → 🟣6 → ⚪7 → 🔴1 → 🟠2 → 🟡3 → 🟢4
2.交换过程
让我们来看看第一步的交换是如何发生的:
原始: 🔴1 🟠2 🟡3 🟢4 🔵5 🟣6 ⚪7
位置: 0 1 2 3 4 5 6第一个交换: 🔴1 ↔ ⚪7[⚪7 🟠2 🟡3 🟢4 🔵5 🟣6 🔴1]第二个交换: 🟠2 ↔ 🟣6[⚪7 🟣6 🟡3 🟢4 🔵5 🟠2 🔴1]第三个交换: 🟡3 ↔ 🔵5[⚪7 🟣6 🔵5 🟢4 🟡3 🟠2 🔴1]最后一个交换: 🟢4 ↔ 🟢4 (中间元素与自己交换,不变)结果: [⚪7 🟣6 🔵5 🟢4 🟡3 🟠2 🔴1]
3.为什么这个方法有效?
把数组想象成两部分:
部分A: 🔴1 🟠2 🟡3 🟢4
部分B: 🔵5 🟣6 ⚪7
我们的目标是交换这两部分:
部分B + 部分A: 🔵5 🟣6 ⚪7 🔴1 🟠2 🟡3 🟢4
三步法魔术
1. 整体翻转:(A+B)反转 = B反转+A反转
🔴1🟠2🟡3🟢4🔵5🟣6⚪7 → ⚪7🟣6🔵5🟢4🟡3🟠2🔴1
2.前K个翻转:B反转再反转 = B正常
⚪7🟣6🔵5🟢4🟡3🟠2🔴1 → 🔵5🟣6⚪7🟢4🟡3🟠2🔴1
3.后(N-K)个翻转:A反转再反转 = A正常
🔵5🟣6⚪7🟢4🟡3🟠2🔴1 → 🔵5🟣6⚪7🔴1🟠2🟡3🟢4
最终得到:B + A 完成!
记忆口诀
📌 全部翻转 → 📌 前K个翻转 → 📌 剩余(后N-K个)翻转 = 🎉 旋转成功!
这样,我们就可以得到逆置需要使用的函数了:
翻转工具函数
// 🛠️ 翻转工具函数
void reverse(int* nums, int start, int end) {while (start < end) {// 🔄 交换两个位置的积木int temp = nums[start];nums[start] = nums[end];nums[end] = temp;// 👉👈 两边向中间移动start++;end--;}
}