荷兰国旗问题:Dutch National Flag Problem

a、给定一个序列arr,和一个数字num,把 > num的放在数组右边,把 <= num的放在数组左边
        b、给定一个序列arr,和一个数字num,把>num的放在数组右边,把 < num的放在数组左边,等于的放在数组中间
        a,b题目的要求:额外空间复杂度O(1),时间复杂度O(N)

思路:

题目a思路:对应leftRightPart()方法

当arr[k] <= num:假定有一个<=的区域(用left  =  -1代表 <= num的初始区域),k指向当前的值(k从0开始),如果arr[k] <= num,交换当前指向的值与 <= 区域下一位的值,left ++(让<=这个区域往数组右边推移),让k ++,交换的目的是为了让小的值纳入到<=的区域内,这个区域内的经过上述操作后就都是 <= num的值。

当arr[k] > num:这时候直接k ++,直到k走到数组越界为止,整个过程即可完成,k越过的都是比num大的值,k 和 left + 1位置(<=区域下一位)交换的值都是将小的值纳入 <= 区域的过程。

    题目b思路:对应leftMidRightPart()方法

当arr[k] < num:假定有两个区域(用left = -1代表小于num的初始区域,用right = arr.length代表大于num的初始区域),k指向当前的值(k从0开始),如果arr[k]  <  num,arr[k] 和 arr[left+1]的值做交换,然后left ++k ++

当arr[k] > num:如果arr[k]  >  num,交换arr[k] 和 arr[arr.length-1]的值,然后right --,right的这个处理是为了将刚才调整到的位置上的值纳入到   > num 的区域内 。   这里arr[arr.length-1]    是 > num 区域的前一位的值,那么交换完,后面的值换到了k的位置,这时候k位置的值不确定它与num的关系,所以让循环的索引 i -= 1,这一步的目的是将已经执行过的一次循环往回调了一下,让换过来的在k位置上的值重新进入判断逻辑。

当arr[k] = num:直接跳过,然后k ++

        当k == right时,return,处理完成。

小结:其实b思路就好像在一个桌子上放着一串带有数组的棋子,给定一个规则:确定一个数字,大于这个数字的棋子我拿,小于这个数字的棋子你拿,和这个数字相等的谁也别动。你和我分别代表< num的区域和 > num的区域,这两个区域外侧的都是待处理的数字,待处理区域初始为整个数组。a思路就是b思路的简化.....

package com.kali.quick;import java.util.Arrays;/*** 荷兰国旗问题:Dutch National Flag Problem*      1.给定一个序列arr,和一个数字num,把 > num的放在数组右边*      把 <= num的放在数组左边*      2.给定一个序列arr,和一个数字num,把>num的放在数组右边*      把 < num的放在数组左边,等于的放在数组中间*      1,2的要求:额外空间复杂度O(1),时间复杂度O(N)*/
public class NetherlandsFlagIssue {public static void main(String[] args) {int[] arr = {1,3,4,2,7,5,11,2,6,9,8,15,7,7,9,7,7,6,4};/*int[] process = process(arr, 3);System.out.println(Arrays.toString(process));*//*int[] ints = leftRightPart(arr, 4);System.out.println(Arrays.toString(ints));*/int[] tar = leftMidRightPart(arr, 7);System.out.println(Arrays.toString(tar));}//<= num在左边,> num在右边public static int[] leftRightPart(int[] arr,int num){int left = -1;int k = 0;for (int value : arr) {if (value <= num) {swap(arr, k, left + 1);left++;}k++;}return arr;}//真正意义上的荷兰旗问题 < num在左边,> num在右边 = num在中间public static int[] leftMidRightPart(int[] arr,int num){int left = -1;int right = arr.length;int k = 0;for (int i = 0; i < arr.length; i++) {if(k == right){break;}if (arr[i] < num) {swap(arr, k, left+1);left++;k ++;}else if(arr[i] > num){swap(arr,k,right-1);i -= 1;right --;}else{k ++;}}return arr;}public static void swap(int[] arr,int m,int n){int temp = arr[m];arr[m] = arr[n];arr[n] = temp;}//按自己想法写的,只实现了<= num在左边,> num在右边,可能不满足复杂度要求public static int[] process(int[] arr,int wall){int[] des = new int[arr.length];int L = 0;for (int item : arr) {if (item <= wall) {des[L] = item;L++;}}for (int value : arr) {if (value > wall) {des[L++] = value;}}return des;}
}

荷兰国旗问题的解决:额外空间复杂度O(1),时间复杂度O(N)相关推荐

  1. 多图养眼!Partition,荷兰国旗问题与随机快排

    快速排序的思想是通过一次排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归方式实现,以此达到整 ...

  2. 算法练习day4——190321(小和、逆序对、划分、荷兰国旗问题)

    归并排序快的原因: 后面的排序利用了前面排序的结果!!! 1.小和问题 在一个数组中, 每一个数左边比当前数小的数累加起来, 叫做这个数组的小和. 求一个数组的小和. 例子:[1,3,4,2,5] 1 ...

  3. 荷兰国旗问题(分三块)

    在说 "荷兰国旗" 问题之前,首先来看一个引例. 给定一个数组arr,和一个数num,请把小于等于num的数放在数组的左边,大于num的数放在数组的右边.要求额外空间复杂度O(1) ...

  4. 【算法】荷兰国旗问题

    本文为博主九师兄(QQ:541711153 欢迎来探讨技术)原创文章,未经允许博主不允许转载. 文章目录 1.概述 2.问题一 2.1 暴力方法 2.2 双指针方法 1.2 问题二(荷兰国旗问题) 1 ...

  5. 快速排序(由荷兰国旗问题到快排)

    文章目录 一.荷兰国旗问题 荷兰国旗解题思路 荷兰国旗代码 二.荷兰国旗到快排 时间复杂度分析 稳定性分析 一.荷兰国旗问题 在了解快排之前,我们首先了解荷兰国旗问题 给定一个数组arr,和一个整数n ...

  6. 切分数组--荷兰国旗问题

    package org.buptdavid.datastructure.zj.zuo_shen;import java.util.Arrays;/*** @author root* @CalssNam ...

  7. Java实现荷兰国旗问题

    问题描述 现有n个红白蓝三种不同颜色的小球,乱序排列在一起,请通过两两交换任意两个球,使得从左至右的球依次为红球.白球.蓝球.这个问题之所以叫荷兰国旗,是因为将红白蓝三色的小球弄成条状物,并有序排列后 ...

  8. 各种排序算法以及扩展(选择排序,冒泡排序,插入排序,归并排序,最小和问题,堆排序,荷兰国旗问题,快速排序)

    文章目录 基础算法一二课 选择排序 冒泡排序 插入排序 判断数据是否在数组中 找满足>=value的最左位置 ^ 异或符号的多用 一.进行交换 二.数组中有一种数出现了奇数次,其他数都出现了偶数 ...

  9. 荷兰国旗问题(partition)总结

    在之前总结的的快速排序算法中,用到了partition算法,故今天来总结下partition算法和其应用 partition算法,又称为荷兰国旗问题,其主要包括两个问题. 文章目录 1 问题1-二分p ...

最新文章

  1. 2020人工神经网络第一次作业-参考答案第六部分
  2. 切换节点服务器网站,服务器手动切换节点
  3. opencv 通过标定摄像头测量物体大小_视觉激光雷达信息融合与联合标定
  4. Python 内置模块之 asyncio(异步iO)
  5. phpMyAdmin 尝试连接到MySQL 服务器的错误解决方法
  6. Linux服务器---xopps
  7. 【知识图谱系列】基于Randomly Perturb的图谱预训练模型GraphCL
  8. python爬取酷狗音乐歌词_python爬虫教程:爬取酷狗音乐
  9. Finished, saving caches
  10. vscode远程连接的坑
  11. vue 项目打印时去掉页眉页脚
  12. C# 复制Word(复制全部内容、部分内容、页眉页脚)
  13. Vue2.0基本用法之组件的注册和传值(父子props,插槽,$emit)和学写购物车
  14. 完美世界手游服务器显示不了,完美世界手游登陆不了怎么办 完美世界手游无法登陆解决方案...
  15. APP开发要么快要么死!
  16. Springboot+vue 社团管理系统(前后端分离)
  17. Direct3D中的纹理映射
  18. 中兴网络设备交换机路由器查看MAC地址表项命令方法
  19. 同济大学计算机网络综合实验报告,同济计算机复试总结
  20. 【淘客基地各项目拉新活动海报已开启】公告

热门文章

  1. python画出roc曲线 auc计算逻辑_Python画ROC曲线和AUC值计算
  2. 三菱数控CNC学习路线图
  3. UML测试题(用例规约)
  4. 康佳的转型之路:净利润再提升,开年又出“王炸”
  5. 如何让开关打开_打开汽车引擎盖很简单?做对的新手司机没几个,这种做法很危险...
  6. Python-pandas的dropna()方法-丢弃含空值的行、列
  7. 交换两个变量值的几种方法;
  8. 从零开始搭建公司微服务架构技术栈,这套架构绝了...
  9. app提交App Store 报错
  10. 用Word画原型{转载}