***leetcode刷题_(quicksort,dutch partition problem)_code75(颜色分类)

17 篇文章 0 订阅

code75: Sort Colors
an array with n objects colored red, white or blue, sort them in-place so that objects of the same color are adjacent, with the colors in the order red, white and blue.

Here, we will use the integers 0, 1, and 2 to represent the color red, white, and blue respectively.

Note: You are not suppose to use the library’s sort function for this problem.

Example:

Input: [2,0,2,1,1,0]
Output: [0,0,1,1,2,2]
Follow up:

A rather straight forward solution is a two-pass algorithm using counting sort.
First, iterate the array counting number of 0’s, 1’s, and 2’s, then overwrite array with total number of 0’s, then 1’s and followed by 2’s.
Could you come up with a one-pass algorithm using only constant space?

解答:
根据题意最简答的方法就是遍历一遍确定数目 然后直接新建数组输出。
这个代码省略。
但是要求不产生额外的空间!

对于排序,不产生额外空间的排序–交换类排序。其中复杂度低的 是快排。
使用快排解答此题。
一般而言,快排 选取pivot,遍历,大于的排到右边,小于的排到左边。

简单的表示代码为:

    def qsort(self,arr):
        print(arr)
        if len(arr)>=2:
            pivot = arr[0]
            l = []
            r = []
            for a in arr[1:]:
                if a < pivot:
                    l.append(a)
                else:
                    r.append(a)
            print(l, r)
            return self.qsort(l)+[pivot]+self.qsort(r)
        else:
            return arr

这个是比较好理解的版本,但是依然产生了额外的空间,接下来写正常的交换版本。

def quicksort2(arr,l,r)
	if l<r:
	    pivot = arr[l]
	    i=l
	    j=r
	    while i<j:
	        while i<j and arr[j]>=pivot:
	            j+=1
	        arr[i] = arr[j]
	        while i<j and arr[i]<=pivot:
	            i+=1
	        arr[j] = arr[i]
	    arr[i] = pivot
	    quicksort2(arr,l,i-1)
	    quicksort2(arr,i+1,r)
    

(双闭区间,终止时l=r)
这个是没有返回值 而且没有 额外空间占用的方法。
简而言之就是:
1 选取最左作为pivot
2 设置左右起始遍历点
3 先从右开始遍历,如果>=pivot(也就是正常),则-=1,继续判断;否则跳出当前 将这个值 赋给i对应的位置(这个时候是覆盖了pivot的index的值的)
4 然后从左遍历,对应 3 类似的操作。
5 循环3 4 直到索引重合
6 重合的点就是pivot应该在的位置,将其赋值为pivot(因为前面起始多了一个其他的值一直在循环内操作,将其取代即可)
7 分为左右部分进入下一层的快排。

然后对应此题。
可以直接使用快排进行解题。事实证明也没问题。

优化:
题目相比普通快排可以解决的问题有所不同:只有三个大小的值。
这就是 荷兰国旗排序问题
考虑如何进行优化。
也就是说最终应该只有三个分区。我们定义三个参数表示三个分区的index
中间的1分区用temp表示(初始0) 0为start(初始0)2为end(初始len-1)。
问题的关键就在 temp与end交叉。
开始遍历:
1 如果为0:交换temp start,temp+1, start+1(交换后的temp不可能为2了,因为2都被拖到后面去了,而且只有1才会使temp与start分开。所以temp+1)
2 如果为1:temp+1
3 如果为2:交换temp end. blue-1(交换后的temp可能为0,所以需要再判断,temp不变)
最后的范围是:如果temp=end也要进行最后的一次操作(因为最后换回来0的时候还需要进行最后的一步确认。)
总结:start是1的起始index,end是1的终止index,temp是2的开始index

代码:

def quicksort3(arr):
    start,end = 0,len(arr)-1
    temp = 0
    while temp<=end:
        if arr[temp]==0:
            arr[start],arr[temp] = arr[temp],arr[start]
            temp+=1
            start+=1
        elif arr[temp]==1:
            start+=1
        else:
            arr[end],arr[temp] = arr[temp],arr[end]
            end-=1

PS: 本篇 需要重点理解快排,包括概念 以及具体实现方式:有无额外空间,有无参数,优化等。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值