Partition Array

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);

这样。。。

时间: 2024-08-25 01:55:28

Partition Array的相关文章

Lintcode31 Partition Array solution题解

[题目描述] 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 fir

leetcode:Partition Array by odd and even

1. Partition an integers array into odd number first and even number second. Given [1, 2, 3, 4], return [1, 3, 2, 4] 2.思路 1.通过两次遍历,不合算. 2.一次遍历,一个从头,一个从尾,如果碰到偶数,兑换位置,此方法为排序. 3. public void partitionArray(int[] nums) { int start = 0, end = nums.length

Partition Array by Odd and Even

Partition an integers array into odd number first and even number second. 剑指offer的一道题,把所有奇数移动到偶数前面,其实是partition的双端解法,利用双指针.先检测两边合格的元素,都不合格,则交换,继续. 需要注意的是: 1.移动时,防止全部是偶数或者全部是奇数的情况,防止移动时越界. 2.交换时,仍然需要防止越界,全奇数或者全偶数,则left== right, 此时不应该交换. 3.注意判断奇偶时,利用位运

【leetcode】1043. Partition Array for Maximum Sum

题目如下: Given an integer array A, you partition the array into (contiguous) subarrays of length at most K.  After partitioning, each subarray has their values changed to become the maximum value of that subarray. Return the largest sum of the given arr

(Easy) Partition Array Into Three Parts With Equal Sum - LeetCode

Description: Given an array A of integers, return true if and only if we can partition the array into three non-empty parts with equal sums. Formally, we can partition the array if we can find indexes i+1 < j with (A[0] + A[1] + ... + A[i] == A[i+1]

LintCode &quot;Partition Array by Odd and Even&quot;

One pass in-place solution: all swaps. class Solution { public: /** * @param nums: a vector of integers * @return: nothing */ void partitionArray(vector<int> &nums) { size_t len = nums.size(); int i = 0, io = 0, ie = len - 1; while (io < ie)

快速排序中的partition函数的枢纽元选择,代码细节,以及其标准实现

很多笔试面试都喜欢考察快排,叫你手写一个也不是啥事.我很早之前就学了这个,对快速排序的过程是很清楚的.但是最近自己尝试手写,发现之前对算法的细节把握不够精准,很多地方甚至只是大脑中的一个映像,而没有理解其真正的本质意图.于是今天结合了<数据结构>(严蔚敏),和<算法导论>进行一番探究. 首先先给出快速排序的严蔚敏版的实现(实际上这部分的partition也是算法导论里面思考题的实现方式,细节可能不一样): 1 public class QuickSort implements So

Partition算法及Partition算法用于快速排序

JavaScript简单方便,所以用JavaScript实现,可以在Chrome控制台下观察运行结果.主要实现Partition算法,比如输入为   var array = [4, 2, 1, 3, 6, 8, 9, 7, 5];   partition(array, 0, 8); 那么按照array[0]即4进行划分,结果为 [3, 2, 1, 4, 6, 8, 9, 7, 5] ?1. [代码][JavaScript]代码 // 先来看Partition算法,Partition算法是快速排序

彻底解密WordCount运行原理(DT大数据梦工厂)

主要内容: 数据流动视角解密WordCount RDD依赖关系视角解密WordCount DAG与Lineage的思考 ==========数据流动视角============ 新建文件,里面输入 Hello Spark Hello Scala Hello Hadoop Hello Flink Spark is awesome 修改代码: package com.dt.spark.SparkApps.cores; import java.util.Arrays; import java.util