题目
给定一个数组arr,和一个数num,请把小于等于num的数放在数组的左边,大于num的 数放在数组的右边。要求额外空间复杂度O(1),时间复杂度O(N)
- 最值得关注的是空间复杂度O(1),意味着不能开辟新的数组空间
- 设定一个小于区间,区间指针从-1开始,当arr[i]<=num 时,将arr[i]和小于区间的下一个位置数互换,然后区间指针+1,将arr[i]囊括进去;当arr[i]>num时,跳过即可
- 价值是如何在空间复杂度为O(1)的情况,进行分左右区间
let arr = [3, 5, 6, 7, 4, 3, 5, 8];
function cutting(arr, num) {
let left = -1;
for (let i = 0; i < arr.length; i++) {
if (arr[i] > num) {
continue;
} else {
[arr[left + 1], arr[i]] = [arr[i], arr[left + 1]];
left++;
}
}
}
cutting(arr, 5);
console.log(arr); //[3, 5, 4, 3, 5, 7, 6, 8],7前面的都比5小,7后面的都比5大
荷兰国旗问题
给定一个数组arr,和一个数num,请把小于num的数放在数组的左边,等于num的数放在数组的中间,大于num的数放在数组的右边。要求额外空间复杂度O(1),时间复杂度O(N)
- 设定一个小于区间,区间指针从-1开始,当arr[i]<num 时,将arr[i]和小于区间的下一个位置数互换,然后区间指针+1,将arr[i]囊括进去;
- 如果arr[i]==num ,跳过
- 设定一个大于区间,区间指针从数组长度的位置开始,当arr[i]>num 时,将arr[i]和大于区间的左边下一个位置互换,然后大于区间指针位置--,将arr[i]囊括进去;当互换后,i位置不++,而是再根据上面的情况判断一次,因为换过来的新数并不知道具体大小
- 当遍历的i==大于区间的指针时,退出循环
let arr = [3, 5, 6, 3, 4, 5, 2, 6, 9, 0];
function cutting(arr, num) {
let left = -1;
let right = arr.length;
for (let i = 0; i <= right; i++) {
if (i == right) {
break;
}
if (arr[i] < num) {
[arr[left + 1], arr[i]] = [arr[i], arr[left + 1]];
left++;
} else if (arr[i] == num) {
continue;
} else {
[arr[i], arr[right - 1]] = [arr[right - 1], arr[i]];
right--;
//使得下轮比较从右边交换过来的数
i--;
}
}
}
cutting(arr, 5);
console.log(arr); //[ 3, 0, 3, 4, 2, 5, 5, 9, 6, 6 ]