Given an array nums of integers and an int k, partition the array (i.e move the elements in "nums") such that:

  • All elements < k are moved to the left
  • All elements >= k are moved to the right

Return the partitioning index, i.e the first index i nums[i] >= k.

Notice

You should do really partition in array nums instead of just counting the numbers of integers smaller than k.

If all elements in nums are smaller than k, then return nums.length

Example

If nums = [3,2,2,1] and k=2, a valid answer is 1.

Challenge

Can you partition the array in-place and in O(n)?

此题是利用快速排序的思想,比较简单吧算是,但是细节需要注意一下。

有个错误解法,如下:

public class Solution {
/**
*@param nums: The integer array you should partition
*@param k: As description
*return: The index after partition
*/
public int partitionArray(int[] nums, int k) {
int left = 0;
int right = nums.length - 1;
while (left < right) {
while (left < right && nums[left] < k) {
left++;
}
while (left < right && nums[right] >= k){
right--;
}
if (left >= right) {
break;
}
swap(nums, left, right);
left++;
right--;
}
return left;
}
public void swap(int[] nums, int a, int b) {
int tmp = nums[a];
nums[a] = nums[b];
nums[b] = tmp;
}
}

这种解法没有考虑到全部数字都小于target的情况,while里面的条件应该是left<=right,这样,即使循环到最后一步,left和right重合,left还要++才能返回数组的长度。

正确解法如下:

public class Solution {
/**
*@param nums: The integer array you should partition
*@param k: As description
*return: The index after partition
*/
public int partitionArray(int[] nums, int k) {
int left = 0;
int right = nums.length - 1;
while (left <= right) {
while (left <= right && nums[left] < k) {
left++;
}
while (left <= right && nums[right] >= k){
right--;
}
if (left > right) {
break;
}
swap(nums, left, right);
left++;
right--;
}
return left;
}
public void swap(int[] nums, int a, int b) {
int tmp = nums[a];
nums[a] = nums[b];
nums[b] = tmp;
}
}

当然我当时的第一想法不是这样做的,while条件里面只要不越界就可以继续循环:

public class Solution {
/**
*@param nums: The integer array you should partition
*@param k: As description
*return: The index after partition
*/
public int partitionArray(int[] nums, int k) {
int left = 0;
int right = nums.length - 1;
while (left < right) {
while (left < nums.length && nums[left] < k) {
left++;
}
while (right >= 0 && nums[right] >= k){
right--;
}
if (left >= right) {
break;
}
swap(nums, left, right);
left++;
right--;
}
return left;
}
public void swap(int[] nums, int a, int b) {
int tmp = nums[a];
nums[a] = nums[b];
nums[b] = tmp;
}
}

也通过了。。。有一点需要注意的是,不要把left++写到while里面,通不过,也是奇怪得很。。。

while (left < nums.length && nums[left++] < k);

这样。。。

Partition Array的更多相关文章

  1. LintCode 373: Partition Array

    LintCode 373: Partition Array 题目描述 分割一个整数数组,使得奇数在前偶数在后. 样例 给定[1, 2, 3, 4],返回[1, 3, 2, 4]. Thu Feb 23 ...

  2. Lintcode: Partition Array

    Given an array "nums" of integers and an int "k", Partition the array (i.e move ...

  3. lintcode 中等题:partition array 数组划分

    题目 数组划分 给出一个整数数组nums和一个整数k.划分数组(即移动数组nums中的元素),使得: 所有小于k的元素移到左边 所有大于等于k的元素移到右边 返回数组划分的位置,即数组中第一个位置i, ...

  4. Lintcode373 Partition Array by Odd and Even solution 题解

    [题目描述] Partition an integers array into odd number first and even number second. 分割一个整数数组,使得奇数在前偶数在后 ...

  5. [Swift]LeetCode915.将分区数组分成不相交的间隔 | Partition Array into Disjoint Intervals

    Given an array A, partition it into two (contiguous) subarrays left and right so that: Every element ...

  6. [Swift]LeetCode1013. 将数组分成和相等的三个部分 | Partition Array Into Three Parts With Equal Sum

    Given an array A of integers, return true if and only if we can partition the array into three non-e ...

  7. LeetCode 1013 Partition Array Into Three Parts With Equal Sum 解题报告

    题目要求 Given an array A of integers, return true if and only if we can partition the array into three  ...

  8. Partition Array into Disjoint Intervals LT915

    Given an array A, partition it into two (contiguous) subarrays left and right so that: Every element ...

  9. Partition Array Into Three Parts With Equal Sum LT1013

    Given an array A of integers, return true if and only if we can partition the array into three non-e ...

随机推荐

  1. fork、vfork、clone区别

    在Linux中主要提供了fork.vfork.clone三个进程创建方法. 问题 在linux源码中这三个调用的执行过程是执行fork(),vfork(),clone()时,通过一个系统调用表映射到s ...

  2. VC编程技巧:IE控件的高级用法

    一.如何显示内存中的 HTML 网页 二.屏蔽 IE 控件的上下文菜单 三.扩展 HTML 脚本中的 external 对象 四.显示 HTML 样式的对话窗 五.执行 HTML 脚本 http:// ...

  3. ActiveMQ之 TCP通讯机制

    ActiveMQ支持多种通讯协议TCP/UDP等,我们选取最常用的TCP来分析ActiveMQ的通讯机制.首先我们来明确一个概念:  客户(Client):消息的生产者.消费者对ActiveMQ来说都 ...

  4. Vim的tag系统

    tag标识符存储在ctags等程序生成的文件里 :tag和<C-]>命令跳转到光标所在符号(若光标不再符号上则为右边第一个符号)的定义处 还有g+鼠标左键和<C-鼠标左键> & ...

  5. linux地址映射1、2、3(☆☆☆)

    欢迎关注瘋耔新浪微博:http://weibo.com/cpjphone 一.线性映射与非线性映射                                                   ...

  6. Oracle DBA常用SQL

    监控SQL 1.监控事例的等待: select event,sum(decode(wait_time,0,0,1)) prev, sum(decode(wait_time,0,1,0)) curr,c ...

  7. bzoj1453

    这是一道好题,按行建线段树,每个点维护上下边界的连通性,详细见代码注释 网上写法不一,自认为比较简单,就放出来相出来献丑吧 ..,..] of longint; //u[]上边界,d[]下边界 s,f ...

  8. UVa 140 (枚举排列) Bandwidth

    题意较复杂,请参见原题=_=|| 没什么好说的,直接枚举每个排列就好了,然后记录最小带宽,以及对应的最佳排列. STL里的next_permutation函数真是好用. 比较蛋疼的就是题目的输入了.. ...

  9. LRU与MRU算法

    1.Cache Hit and Cache Miss 当使用者第一次向数据库发出查询数据的请求的时候,数据库会先在缓冲区中查找该数据,如果要访问的数据恰好已经在缓冲区中(我们称之为Cache Hit) ...

  10. apache开源项目--Derby

    Apache Derby是Apache软件基金会所研发的开放源码数据库管理系统:由于Derby是一个纯Java程式,因此只需要操作系统支援Java虚拟机,Derby便可执行. Derby是特别地为Ja ...