Moderate 找最小排序区间 @CareerCup

例子:数组 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);
	}
}


要实现点击价格区间展示商品,可以在 `PriceCategory` 组件中添加一个点击事件,当用户点击价格分类时,触发展示商品的操作。具体实现步骤如下: 1. 在 `PriceCategory` 组件中添加一个 `onClick` 事件处理函数。 2. 在事件处理函数中,调用父组件传递过来的 `onCategoryClick` 回调函数,并将当前价格分类作为参数传递给它。 3. 在父组件中定义一个 `onCategoryClick` 回调函数,接受价格分类作为参数。 4. 在 `onCategoryClick` 回调函数中根据价格分类,展示对应的商品。 代码示例: ```javascript // 商品列表组件 function ProductList({ products }) { return ( <div> {products.map((product) => ( <div key={product.id}> <p>{product.name}</p> <p>Price: {product.price}</p> </div> ))} </div> ); } // 价格分类组件 function PriceCategory({ price, onCategoryClick }) { let category; if (price < 50) { category = "Cheap"; } else if (price < 100) { category = "Moderate"; } else if (price < 200) { category = "Expensive"; } else { category = "Luxury"; } return ( <div onClick={() => onCategoryClick(category)}> <p>Price: {price}</p> <p>Category: {category}</p> </div> ); } // 父组件 function App() { const products = [ { id: 1, name: "Product 1", price: 50 }, { id: 2, name: "Product 2", price: 80 }, { id: 3, name: "Product 3", price: 120 }, { id: 4, name: "Product 4", price: 250 }, ]; const [selectedCategory, setSelectedCategory] = useState(null); const onCategoryClick = (category) => { setSelectedCategory(category); }; const filteredProducts = selectedCategory ? products.filter((product) => product.price < getPriceRange(selectedCategory)[1] && product.price >= getPriceRange(selectedCategory)[0] ) : products; const getPriceRange = (category) => { switch (category) { case "Cheap": return [0, 50]; case "Moderate": return [50, 100]; case "Expensive": return [100, 200]; case "Luxury": return [200, Infinity]; default: return [0, Infinity]; } }; return ( <div> <h2>Products</h2> <div> {["Cheap", "Moderate", "Expensive", "Luxury"].map((category) => ( <PriceCategory key={category} price={getPriceRange(category)[0]} onCategoryClick={onCategoryClick} /> ))} </div> <ProductList products={filteredProducts} /> </div> ); } ``` 在上述代码中,我们在 `PriceCategory` 组件中添加了一个 `onClick` 事件处理函数,当用户点击价格分类时,会调用父组件传递过来的 `onCategoryClick` 回调函数,并将当前价格分类作为参数传递给它。在父组件中,我们根据当前选中的价格分类过滤商品列表,然后将过滤后的商品列表传递给 `ProductList` 组件进行展示。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值