荷兰国旗问题(java)

问题描述:

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

思路:

(1)首先定义3个游标,less是用来标明其左边是小于num,初始位置为L-1;more是用来标明其右是大于num,初始位置为R+1;current是用来标明目前运动到什么位置了,初始位置当然是L。

(2)运动过程是这样运动的,首先从current开始,将current位置的数值与num进行比较。如果小于num,就将less游标的下一个位置的数值与其交换,此时less++,current++;如果等于num,此时就将current++;如果大于num,就将more游标的前一个位置的数值与其交换,此时more--,然后再将交换后的值(current位置的值)与num比较,再根据大于小于等于重复进行上述操作。

(3)不断地重复(2),直到current与more相撞时,停止。既然是不断重复操作,可使用循环进行

 代码:

package NetherlandsFlag;

import java.util.Arrays;

public class NetherlandsFlag {

	public static void partition(int[] arr,int L,int R,int num) {
		int less=L-1;
		int more=R+1;
		int current=L;
		while (current<more) {
			if (arr[current]<num) {
				change(arr, current++, ++less);
			}else if (arr[current]>num) {
				change(arr, current, --more);
			}else {
				current++;
			}
		}
	}
	//定义交换方法
	public static void change(int[] arr,int i,int j) {
		int tem=arr[i];
		arr[i]=arr[j];
		arr[j]=tem;
	}
	
	public static void main(String[] args) {
		int[] arr= {1,4,3,2,7,6,5,4,3};
		int num=4;
		partition(arr,0,8,num);
		System.out.println(Arrays.toString(arr));
	}
}

运行结果:

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
荷兰国旗问题是一个经典的动态规划问题,它源于一种常见的字符串排序需求:给定一个由红、白、蓝三种颜色组成的数组,其中红色在左,蓝色在右,中间可能夹杂着白色部分,目标是将数组分割成红、白、蓝三部分,使得每部分的颜色相同。这个问题可以通过动态规划来解决,主要利用一个状态数组记录当前序列中前缀的最大红色长度和最小蓝色长度。 Java动态规划实现的大致步骤如下: 1. 初始化:创建一个长度为n+1的状态数组,其中dp = 0, dp[i]代表前i个元素的最优解,初始状态就是序列为空。 2. 状态转移:对于每个位置i,有三种情况: a. 如果第i个元素是红色,那么红色部分不改变,dp[i] = dp[i-1] + 1(如果红色边界能扩展)。 b. 如果第i个元素是白色,那么红色和蓝色边界都不变,因为白色不影响,dp[i] = dp[i-1]。 c. 如果第i个元素是蓝色,那么蓝色部分不改变,dp[i] = dp[i-1],但红色边界缩小到0,因为蓝色结束了。 3. 最终结果:dp[n]就是整个序列的最优解,即最终的红色、白色和蓝色部分的长度。 动态规划代码示例: ```java public int hIndex(int[] nums) { int n = nums.length; int[] dp = new int[n + 1]; for (int i = 1; i <= n; i++) { if (nums[i - 1] == 0) { dp[i] = Math.min(dp[i - 1], i); } else { dp[i] = dp[i - 1]; } if (nums[i - 1] > 0) { dp[i] = Math.max(dp[i], dp[i - nums[i - 1]] + 1); } } return dp[n]; } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值