有苦有乐的算法 --- 有序数组中的元素存在问题、最左元素问题和无序数组局部最小问题

25 篇文章 0 订阅
这篇博客介绍了如何在有序数组中高效地查找指定元素及其最左位置,以及在无序数组中找到局部最小元素的方法。通过二分查找技术,实现了在数组中搜索目标元素的算法,对于局部最小元素,通过比较相邻元素确定其位置。这些算法适用于数据处理和搜索场景。
摘要由CSDN通过智能技术生成

一个有序数组,判断是否含有一个元素

解析:
给定一个数组
在这里插入图片描述

如果需要判断是否存在的元素为3。
首先找到数组的中间元素;
在这里插入图片描述

如果此元素为3,结束;
如果不是,此元素与3比较,此元素如果大于3,在从此元素左边的部分数组寻找中间元素,以此类推。
在这里插入图片描述

如果查找到最后都不是3,证明3在数组中不存在。

代码:
public static boolean isExistInArray(int[] sortedArr, int num) {
if (sortedArr == null || sortedArr.length == 0) {
return false;
}

	int L = 0;
	int R = sortedArr.length - 1;
	int mid = 0;
	// L..R
	while (L < R) { // L..R 至少两个数的时候
		mid = L + ((R - L) >> 1);
		if (sortedArr[mid] == num) {
			return true;
		} else if (sortedArr[mid] > num) {
			R = mid - 1;
		} else {
			L = mid + 1;
		}
	}
	return sortedArr[L] == num;
}

一个有序数组,查找一个元素的最左位置

解析:
给定一个数组
在这里插入图片描述

如果需要判断是否存在的元素为3。
首先找到数组的中间元素;
如果此元素为3,记录临时索引,在从此元素左边的部分数组寻找中间元素;
如果不是,此元素与3比较,此元素如果大于3,在从此元素左边的部分数组寻找中间元素,以此类推。
在这里插入图片描述

查找到最后,临时索引就是元素的最左位置。

代码:

public static int nearestIndex(int[] arr, int value) {
	int L = 0;
	int R = arr.length - 1;
	int index = -1; // 记录最左的对号
	while (L <= R) { // 至少一个数的时候
		int mid = L + ((R - L) >> 1);
		if (arr[mid] >= value) {
			index = mid;
			R = mid - 1;
		} else {
			L = mid + 1;
		}
	}
	return index;
}

一个无序且相邻元素不相等的数组,查找一个局部最小元素

解析:
给定一个数组
第一个元素小于第二个元素,说明第一个元素为局部最小,倒数第一个元素小于倒数第二个元素,说明倒数第一个元素为局部最小。
因为第一个元素和第二个元素不相等,倒数第一个元素和倒数第二个元素不相等,此数组元素的值一定存在一个变化曲线
在这里插入图片描述

首先找到数组的中间元素;
如果此元素左面的值大于此元素,此元素右的值大于此元素,说明找到了;
如果此元素左面的值小于此元素,在左面的部分数组中找中间元素,再次判断;
如果此元素右面的值小于此元素,在右面的部分数组中找中间元素,再次判断。
以此类推,即可找到。

代码:

public static int getLessIndex(int[] arr) {
	if (arr == null || arr.length == 0) {
		return -1; // no exist
	}
	if (arr.length == 1 || arr[0] < arr[1]) {
		return 0;
	}
	if (arr[arr.length - 1] < arr[arr.length - 2]) {
		return arr.length - 1;
	}
	int left = 1;
	int right = arr.length - 2;
	int mid = 0;
	while (left < right) {
		mid = (left + right) / 2;
		if (arr[mid] > arr[mid - 1]) {
			right = mid - 1;
		} else if (arr[mid] > arr[mid + 1]) {
			left = mid + 1;
		} else {
			return mid;
		}
	}
	return left;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值