Moderate 找最小排序区间 @CareerCup

原创 2013年12月03日 01:55:04

例子:数组 1, 2, 4, 7, 10, 11, 7, 12, 6, 7, 16, 18, 19  只要对下标3到9之间的元素排序,就能使整个数组有序

思路是:

// Left: 1, 2, 4, 7, 10, 11
// Middle: 7, 12
// Right: 6, 7, 16, 18, 19

1 找到左边递增序列的最右(最大)的那个元素 11

2 找到右边递增序列最左(最小)的那个元素 6

3 找到中间序列的最小元素 7

4 找到中间序列的最大元素 12

5 找到左边递增序列中比中间序列最小元素(7)还要小或等于的下标(元素7,下标3)

6 找到右边递增序列中比中间序列最大元素(12)还要大或等于的下标的前一个元素(元素7,下标9)



package Moderate;

/**
 * Given an array of integers, write a method to find indices  m and n such that if you
sorted elements m through n, the entire array would be sorted. Minimize n-m (that
is, find the smallest such sequence).

给定了一个整数数组,写一个方法来找到下标m和n使得如果把m到n之间的数排序,
则整个数组也会被排好序。要使得m到n的区间尽量小

 *
 */
public class S17_6 {
	
	// 找到左边递增序列的最右(最大)的那个元素 11
	public static int findEndOfLeftSubsequence(int[] array) {
		for (int i = 1; i < array.length; i++) {
			if (array[i] < array[i - 1]) {	// 不再递增了!
				return i - 1;
			}
		}
		return array.length - 1;
	}

//	 找到右边递增序列最左(最小)的那个元素 6
	public static int findStartOfRightSubsequence(int[] array) {
		for (int i = array.length - 2; i >= 0; i--) {
			if (array[i] > array[i + 1]) {		// 不再递减了
				return i + 1;
			}
		}
		return 0;
	}

	// 找到左边递增序列中比中间序列最小元素(7)还要小或等于的下标(元素7,下标3)
	public static int shrinkLeft(int[] array, int min_index, int start) {
		int comp = array[min_index];
		for (int i = start - 1; i >= 0; i--) {
			if (array[i] <= comp) {
				return i + 1;
			}
		}
		return 0;
	}

	// 找到右边递增序列中比中间序列最大元素(12)还要大或等于的下标的前一个元素(元素7,下标9)
	public static int shrinkRight(int[] array, int max_index, int start) {
		int comp = array[max_index];
		for (int i = start; i < array.length; i++) {
			if (array[i] >= comp) {
				return i - 1;
			}
		}
		return array.length - 1;
	}

	public static void findUnsortedSequence(int[] array) {
		// find left subsequence
		int end_left = findEndOfLeftSubsequence(array);

		// find right subsequence
		int start_right = findStartOfRightSubsequence(array);

		// find min and max element of middle
		int min_index = end_left + 1;
		if (min_index >= array.length) {
			// System.out.println("The array is already sorted.");
			return; // Already sorted
		}

		int max_index = start_right - 1;
		for (int i = end_left; i <= start_right; i++) {
			if (array[i] < array[min_index]) {
				min_index = i;
			}
			if (array[i] > array[max_index]) {
				max_index = i;
			}
		}

		// slide left until less than array[min_index]
		int left_index = shrinkLeft(array, min_index, end_left);

		// slide right until greater than array[max_index]
		int right_index = shrinkRight(array, max_index, start_right);

		if (validate(array, left_index, right_index)) {
			System.out.println("TRUE: " + left_index + " " + right_index);
		} else {
			System.out.println("FALSE: " + left_index + " " + right_index);
		}
	}

	/*
	 * Validate that sorting between these indices will sort the array. Note
	 * that this is not a complete validation, as it does not check if these are
	 * the best possible indices.
	 */
	public static boolean validate(int[] array, int left_index, int right_index) {
		int[] middle = new int[right_index - left_index + 1];
		for (int i = left_index; i <= right_index; i++) {
			middle[i - left_index] = array[i];
		}
		java.util.Arrays.sort(middle);
		for (int i = left_index; i <= right_index; i++) {
			array[i] = middle[i - left_index];
		}
		for (int i = 1; i < array.length; i++) {
			if (array[i - 1] > array[i]) {
				return false;
			}
		}
		return true;
	}

	public static void main(String[] args) {
		int[] array = { 1, 2, 4, 7, 10, 11, 7, 12, 6, 7, 16, 18, 19 };
		// Left: 1, 2, 4, 7, 10, 11
		// Middle: 7, 12
		// Right: 6, 7, 16, 18, 19
		findUnsortedSequence(array);
	}
}


相关文章推荐

RMQ求区间最值(最大最小)

  • 2015年08月28日 15:36
  • 614KB
  • 下载

prim算法改进,C语言,用堆排序找到最小边开始,可读取文件

1.不从节点1开始找,从图中最小的边开始找。其中求最小边用堆排序的算法 2.其余与yyprim类似; 3.将下面数据保存到1.t...

关于区间最小覆盖的问题总结(以zoj 3197 Google Book 为例)

Google Book Time Limit: 1 Second      Memory Limit: 32768 KB You, the best hacker in the world...
  • caduca
  • caduca
  • 2014年08月21日 20:50
  • 3542

步步为营(六)贪心(5)最小区间覆盖问题

关于区间相关贪心算法的讨论,点击这里,有一份详细的资料,还有几个问题没有说到 《浅谈信息学竞赛中的区间问题》 在贪心算法的层面上,我们能够进行解决的区间覆盖,指的就是最小区间覆盖问题。 ...

HDU 4106 Fruit Ninja 区间k覆盖问题 最小费用流

题目链接:点击打开链接 题意: 给定n长的序列,m ,k 选择一些数使得 选择的数和最大。输出和。 限制:对于任意的区间[i, i+m]中至多有k个数被选。 思路: 白书P367,区间k覆...

POJ 2680 —— 最小费用流求解区间图的最大权独立集问题

Intervals Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 5967   Acce...
  • zkzxmzk
  • zkzxmzk
  • 2013年10月31日 02:26
  • 894

*[Lintcode]Interval Sum区间最小数

Given an integer array (index from 0 to n-1, where n is the size of this array), and an query list. ...

hdu1394 Minimum Inversion Number 最小逆序数 线段树单点更新区间查询

Minimum Inversion Number Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Jav...

UVA-11584-Partitioning by Palindromes(区间DP 最小回文串数量)

We say a sequence of characters is a palindrome if it is the same written forwards and backwards....

poj 2376 最小区间覆盖问题

http://poj.org/problem?id=2376 Description Farmer John is assigning some of his N (1
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Moderate 找最小排序区间 @CareerCup
举报原因:
原因补充:

(最多只允许输入30个字)