数组划分
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是合理的(这种边界问题慢慢来吧,一开始,不容易熟练)
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是合理的(这种边界问题慢慢来吧,一开始,不容易熟练)
相关文章推荐
- 快速排序
- C#快速排序算法实例分析
- C++快速排序的分析与优化详解
- js实现数组冒泡排序、快速排序原理
- php简单实现快速排序的方法
- Java 快速排序(QuickSort)原理及实现代码
- 快速排序和分治排序介绍
- java 算法之快速排序实现代码
- Java实现快速排序算法(Quicktsort)
- Java中的数组排序方式(快速排序、冒泡排序、选择排序)
- 快速排序的原理及java代码实现
- C/C++实现快速排序的方法
- c语言实现冒泡排序、希尔排序等多种算法示例
- 深入单链表的快速排序详解
- C++实现八个常用的排序算法:插入排序、冒泡排序、选择排序、希尔排序等
- JavaScript实现快速排序的方法
- C#使用委托实现的快速排序算法实例
- C语言的冒泡排序和快速排序算法使用实例
- javascript与Python快速排序实例对比
- php实现快速排序的三种方法分享