您的位置:首页 > 其它

数组划分

2016-04-24 17:21 197 查看
题目描述:给出一个整数数组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是合理的(这种边界问题慢慢来吧,一开始,不容易熟练)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  快速排序