码迷,mamicode.com
首页 > 编程语言 > 详细

数组划分

时间:2016-04-29 19:37:23      阅读:231      评论:0      收藏:0      [点我收藏+]

标签:

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

1. 所有小于k的元素移到左边

2. 所有大于等于k的元素移到右边

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


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


很简单的快排分割的应用。我们的思路跟前面讲过的“颜色分类”(详见:点击打开链接)是一样的,这道题比颜色分类甚至还要简单,因为它所有的元素只有两种情况:

1. 小于k的,靠拢在数组左边即可

2. 大于等于k的,靠拢在数组右边

而因为只有两种情况,我们甚至在做元素交换的时候都不需要对两侧分别交换,只需要对一侧交换就行(如果这里没明白我在说什么,一会直接看代码)

所以说,思路很明确了:设置两个指针left和right,left用来累计小于k的元素,right用来累计大于等于k的,通过快排的交换方法,实现分割。

代码如下:

class Solution:
    """
    @param nums: The integer array you should partition
    @param k: As description
    @return: The index after partition
    """
    def partitionArray(self, nums, k):
        n = len(nums)
        if n == 0:
            return 0
        # left指向数组的第一个位置
        # right指向数组的最后一个位置的后一个位置
        left, right = 0, n
        # 当left == right时,说明数组已经遍历完
        while left < right:
            if nums[left] < k:
                left += 1
            # 执行else,说明至少有一个元素是大于等于k的
            else:
                right -= 1
                nums[left], nums[right] = nums[right], nums[left]
                
        return right
        # write your code here
        # you should partition the nums by k
        # and return the partition index as description
这里有一个技巧,就是返回的值到底应该在代码中表示成什么?

这个当然根据你对初始时指针的设定有关,如果正常设置初始值会导致程序错误的话,比如,我设置left = 0, right = n - 1,那你会发现不论怎么返回都有问题(试考虑数组元素全小于k或者全大于等于k的特殊情况),所以,我们一般情况下会将其中一个指针给一个提前量,比如,上面的代码中令right = n,再返回就没有问题了。需要注意第18行的注释,想一想,如果没有元素大于等于k,else不执行,那么返回right刚刚合适,他在数组最后一位再往后一位,而如果执行了else,20行的right -= 1就一定能保证right是合理的(这种边界问题慢慢来吧,一开始,不容易熟练)



数组划分

标签:

原文地址:http://blog.csdn.net/guoziqing506/article/details/51234397

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!