杂谈 · 荷兰国旗问题(思路)

目录

一、内容

二、分析

问题一

问题二

三、总结


一、内容

问题一

        给定一个数组arr,和一个num,请把小于等于num的数放在数组的左边,大于num的数放在数组的右边。要求额外空间复杂度O(1),时间复杂度O(N)

问题二(荷兰国旗问题)

        给定一个数组arr,和一个num,请把小于num的数放在数组的左边,等于num的数放在数组的中间,大于num的数放在数组的右边。要求额外空间复杂度O(1),时间复杂度O(N)

二、分析

问题一

定义一个小于等于区域(从数组最左侧开始,不包含第一个元素)

1) arr[i] <= num,arr[i]和小于等于区域的下一个数交换,小于等于区右扩,i++

2) arr[i] > num, i++

原理:右侧为待定区域,小于等于区域(已经满足条件),小于等于区域右侧到 i 的区域是大于区域。即随着 i 的遍历的过程中小于等于区域推着大于区域往右走,当小于等于区域把大于区域推到整个数组范围的时候,即可满足条件

问题二

问题二(荷兰国旗问题)即为问题一的升级版

定义一个小于区域(从数组最左侧开始,不包含第一个元素),再定义一个大于区域(从数组最右侧开始,不包含最后一个元素)

1) arr[i] < num,arr[i]和小于区域的下一个数交换,小于区右扩,i++

2) arr[i] == num, i++

3) arr[i] > num,arr[i]和大于区域的前一个数交换,大于区域左扩,i不变

原理:在问题一的基础上,增加了大于区域。随着i的遍历小于区域向右推进,大于区域向左推进,当 i 推进到大于区域的初始位置时,既满足条件

三、总结

        整体思想是基于题目条件进行的区块划分,在 i 遍历的过程中将满足条件的元素归于自己的区块,以此达到条件

        另外提一嘴:快排也可以采用这个思路哦(感兴趣的小伙伴们可以自己去尝试一下)

猜你喜欢

转载自blog.csdn.net/H_Greddy/article/details/127135625