算法与数据结构:荷兰国旗问题
问题:给定一个无序数组arr,元素只有0,1,2三种取值
要求:重新排列数组,使得所有值为0的元素在数组左边,值为1的元素在数组右边,值为2的元素在数组中间。
思路:设三种数组索引,mid, left, right, 假设一种中间过程,[0, left) 区间内元素的值为0,(right, len-1] 区间内元素为1, [left, mid)区间内元素为2,[mid, right] 区间内元素未排序
arr[mid]的值分为3种情况:
1. arr[mid] == 2, 为保持中间状态,mid向右移动一步即可
2. arr[mid] == 0, 因为arr[left]为2, 交换arr[mid]和arr[left], left和mid各向右移动一步
3. arr[mid] == 1, 交换arr[right]和arr[mid], right向左移动一步
依据上述的迭代方法,最终可以使得[mid, right]区间为空,到这里时,迭代完成。此时mid>right。因此只要mid<=right就必须不断迭代。
依据上述思路,可以很快写出代码:
void rearrange(int* arr, int len) { if (! arr || len == 0) return; int right = len - 1; int left = 0; int mid = 0; while (mid <= right) { int val = arr[mid]; if (val == 0) { swap(arr[left], arr[mid]); left++; mid++; } else if (val == 2) { mid++; } else { swap(arr[mid], arr[right]); right--; } } }