描述
给出一个整数数组 nums 和一个整数k划分数组(即移动数组 nums 中的元素),使得:
所有小于k的元素移到左边
所有大于等于k的元素移到右边
返回数组划分的位置,即数组中第一个位置 i,满足 nums[i] 大于等于 k
注意事项
你应该真正的划分数组 nums,而不仅仅只是计算比k小的整数,如果数组 nums 中的所有元素
都比k小,则返回 nums.length。
挑战
使用 O(n) 的时间复杂度在数组上进行划分。
思路
值得注意的地方是在快速排序算法的各种应用中,下面四个连续判断条件要一致,此算法left不能等于right,在快排中分割值是在数组中挑的,本题中数组元素可能都小于k,可能出现left等于right且在边界点仍满足条件,left++越界的情形
比如数组[7,7,9,8,6,6,8,7,9,8,6,6],k = 10
代码
public class Solution {
/*
* @param nums: The integer array you should partition
* @param k: An integer
* @return: The index after partition
*/
public int partitionArray(int[] nums, int k) {
if (nums == null || nums.length == 0) {
return 0;
}
int left = 0, right = nums.length - 1;
while (left < right) {
while (left < right && nums[left] < k) {
left++;
}
while (left < right && nums[right] >= k) {
right--;
}
if (left < right) {
int temp = nums[left];
nums[left] = nums[right];
nums[right] = temp;
left++;
right--;
}
}
// left = right 情况单独判断,本题之所以在上面的 while 循环中把 = 去掉,
// 是由于题目要求返回数组中第一个位置 i 满足 nums[i] 大于等于 k
// 上述代码已经完成了基本的 partition 功能,但分割点 left = right 处值和 k 的大小关系要特判下
// 此处还可能出现 left 和 right 由于 ++ -- 操作后刚好错开的情形,但下面代码也可以返回正确结果
if (nums[left] >= k) {
return left;
}
return left + 1;
}
}