标签:
题目描述:给出一个整数数组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