LintCode 数组划分

问题描述:

给出一个整数数nums和一个整数k。划分数组(即移动数组nums中的元素),使得:

  • 所有小于k的元素移到左边
  • 所有大于等于k的元素移到右边

返回数组划分的位置,即数组中第一个位置i,满足nums[i]大于等于k。

样例:给出数组nums = [3, 2, 2, 1]和 k=2,返回 1。

挑战:要求在原地使用O(n)的时间复杂度来划分数组。

    本题最直观的思路是直接排序,然后找出i的位置。但是这种方式的时间复杂度为O(nlogn)。若想降低时间复杂度,此处采用两根指针的方法。规定两根指针start和end分别指向数组的首尾,分别向后,向前遍历。若nums[start] > k且nums[end] < k,则交换这两个数。而最终start的值即为i的位置。本题在边界条件的处理时要尤为仔细。代码如下:

public class Solution {
    public int partitionArray(int[] nums, int k) {
	    int start = 0;
	    int end = nums.length - 1;
	    int t = 0;
	    while (end - start >= 0) {
	        if (nums[start] >= k) {
	            if (nums[end] < k) {
	                t = nums[start];
	                nums[start] = nums[end];
	                nums[end] = t;
	            }
	            else {
	                end--;
	            }
	        }
	        else {
	            start++;
	        }
	    }
	    return start;
    }
}

    该方式完成了在原地使用O(n)的时间复杂度来划分数组。

你可能感兴趣的:(刷题心得)