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)的时间复杂度来划分数组。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值