Leetcode学习之二分查找与二叉查找树(1)

开宗明义:本系列基于小象学院林沐老师课程《面试算法 LeetCode 刷题班》,刷题小白,旨在理解和交流,重在记录,望各位大牛指点!


Leetcode学习之二分查找与二叉查找树(1)



1、二分查找

描述已知一个排序数组A,如A=[-1,2,5,20,90,100,207,800];另外一个乱序数组B,B=[50,90,3,-1,207,80],求B中的任意某个元素,是否在A中出现,结果存储在数组C之中。出现用1表示,未出现用0表示,如,C=[0,1,0,1,1,0]
分析
在这里插入图片描述
在这里插入图片描述在这里插入图片描述

1.1 二分查找(递归)

测试代码:

#include <vector>
using namespace std;

bool binary_search(vector<int> &sort_arry,int begin,int end,int target) {//搜索到返回true,否则返回false
	if (target > end) {
		return false;
	}
	int mid = (begin + end) / 2;
	if (target == sort_arry[mid]) {//找到的时候
		return true;
	}
	else if (target < sort_arry[mid]) {
		return binary_search(sort_arry, begin, mid - 1, target);
	}
	else if (target > sort_arry[mid]) {
		return binary_search(sort_arry, mid + 1, end, target);
	}
}

vector<int> search_array(vector<int> &sort_array, vector<int> &random_array) {//A与B
	vector<int> result;
	for (int i = 0; i < random_array.size(); i++) {
		int res = binary_search(sort_array, 0, sort_array.size() - 1, random_array[i]);
		result.push_back(res);
	}
	return result;
}

int main() {
	int A[] = { -1,2,5,20,90,100,207,800 };
	int B[] = { 50,90,3,-1,207,80 };
	vector<int> sort_array;
	vector<int> random_array;
	vector<int> C;
	for (int i = 0; i < 8; i++) {
		sort_array.push_back(A[i]);
	}
	for (int i = 0; i < 6; i++) {
		random_array.push_back(B[i]);
	}
	C = search_array(sort_array, random_array);
	for (int i = 0; i < C.size(); i++) {
		printf(" %d\n", C[i]);
	}
	system("pause");
	return 0;
}

效果图
在这里插入图片描述


1.2 二分查找(循环)

测试代码:

#include <vector>
using namespace std;

bool binary_search(vector<int> &sort_arry, int target) {//搜索到返回true,否则返回false
	int begin = 0;
	int end = sort_arry.size() - 1;
	while (begin <= end) {
		int mid = (begin + end) / 2;
		if (target == sort_arry[mid]) {
			return true;
		}
		else if (target < sort_arry[mid]) {
			end = mid - 1;
		}
		else if (target > sort_arry[mid]) {
			begin = mid + 1;
		}
	}
	return false;
}

vector<int> search_array(vector<int> &sort_array, vector<int> &random_array) {//A与B
	vector<int> result;
	for (int i = 0; i < random_array.size(); i++) {
		int res = binary_search(sort_array, random_array[i]);
		result.push_back(res);
	}
	return result;
}

int main() {
	int A[] = { -1,2,5,20,90,100,207,800 };
	int B[] = { 50,90,3,-1,207,80 };
	vector<int> sort_array;
	vector<int> random_array;
	vector<int> C;
	for (int i = 0; i < 8; i++) {
		sort_array.push_back(A[i]);
	}
	for (int i = 0; i < 6; i++) {
		random_array.push_back(B[i]);
	}
	C = search_array(sort_array, random_array);
	for (int i = 0; i < C.size(); i++) {
		printf(" %d\n", C[i]);
	}
	system("pause");
	return 0;
}

效果图
在这里插入图片描述


2、插入位置(二分查找) LeetCode 35.

题目来源 L e e t C o d e   35.   S e a r c h   I n s e r t   P o s i t i o n LeetCode \ 35. \ Search \ Insert \ Position LeetCode 35. Search Insert Position
描述给定一个排序数组nums(无重复元素)与目标值target,如果target在nums里出现,则返回target所在的下标。如果target在nums里面未出现,则返回target应该插入位置的数组下标,使target插入数组nums后,数组仍有序
在这里插入图片描述
分析
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

测试代码:

#include <vector>
#include <stdio.h>
using namespace std;

class Solution {
public:
	int searchInsert(vector<int>& nums, int target) {
		int index = -1;//最终返回的下标,若找到则为该元素的下标,否则为需要插入的位置
		int begin = 0;//搜索区间左端点
		int end = nums.size() - 1;//搜索区间右端位置
		while (index == -1) {//若index==-1,则说明还未找到正确的位置,持续二分搜索
			int mid = (begin + end) / 2;//计算中心位置
			if (target == nums[mid]) {
				index = mid;//若找到
			}
			else if (target < nums[mid]) {
				if (mid == 0 || target > nums[mid - 1]) {
					index = mid;
				}
				end = mid - 1;//这边代码的意思是如果target小于中点,更新区间右端点
			}
			else if (target > nums[mid]) {
				if (mid == nums.size() - 1 || target < nums[mid + 1]) {
					index = mid + 1;
				}
				begin = mid + 1;//如果target大于终点,更新区间左端点
			}
		}
		return index;
	}
 };

int main() {
	int test[] = { 1,3,5,6 };
	vector<int> nums;
	Solution solve;
	for (int i = 0; i < 4; i++) {
		nums.push_back(test[i]);
	}

	for (int i = 0; i < 8; i++) {
		printf("i = %d,index = %d \n", i, solve.searchInsert(nums, i));
	}
	system("pause");
	return 0;
}

效果图
在这里插入图片描述


3、区间查找(二分查找)LeetCode 34.

题目来源 L e e t C o d e   34.   S e a r c h   f o r   a   R a n g e LeetCode \ 34. \ Search \ for \ a \ Range LeetCode 34. Search for a Range.
题目描述给定一个排序数组nums(nums里面有重复的元素)与目标值target,如果target在nums中出现,则返回target所在区间的左右端点下标,[左端点,右端点],如果没出现则返回[-1,1]
在这里插入图片描述分析
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
测试代码:

#include <vector>
using namespace std;

int left_bound(vector<int> &nums, int target) {
	int begin = 0;
	int end = nums.size() - 1;

	while (begin <= end) {
		int mid = (begin + end) / 2;
		if (target == nums[mid]) {
			if (target > nums[mid - 1]||mid==nums.size()-1) {
				return mid;
			}
			begin = mid + 1;
		}
		else if (target < nums[mid]) {
			end = mid - 1;
		}
		else if (target > nums[mid]) {
			begin = mid + 1;
		}
	}
	return -1;
}

int right_bound(vector<int>& nums, int target) {
	int begin = 0;
	int end = nums.size() - 1;
	while (begin <= end)
	{
		int mid = (begin + end) / 2;
		if (target == nums[mid]) {
			if (mid == nums.size() - 1 || nums[mid + 1] > target) {
				return mid;
			}
			begin = mid + 1;
		}
		else if (target < nums[mid]) {
			end = mid - 1;
		}
		else if (target > nums[mid]) {
			begin = mid + 1;
		}
	}
	return -1;
}

class Solution {
public:
	vector<int> searchRange(vector<int>&nums, int target) {
		vector<int> result;
		result.push_back(left_bound(nums, target));
		result.push_back(right_bound(nums, target));
		return result;
	}
};

int main() {
	int test[] = { 5,7,7,8,8,8,8,10 };
	vector<int> nums;
	Solution solve;
	for (int i = 0; i < 8; i++) {
		nums.push_back(test[i]);
	}
	for (int i = 0; i < 12; i++) {
		vector<int> result = solve.searchRange(nums, i);
		printf("%d : [%d ,%d]\n", i, result[0], result[1]);
	}
	system("pause");
	return 0;
}

效果图
在这里插入图片描述


4、旋转数组查找(二分查找)LeetCode 33.

题目来源 L e e t C o d e   33.   S e a r c h   i n   R o t a t e d   S o r t e d   A r r a y LeetCode \ 33. \ Search \ in \ Rotated \ Sorted \ Array LeetCode 33. Search in Rotated Sorted Array
描述给定一个排序数组nums(nums中有无重复元素),且nums可能以某个未知下标旋转,给定目标值target,求target知否在nums中出现,若出现则返回所在下标,未出现返回-1
在这里插入图片描述
分析
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
测试代码:

#include <vector>
using namespace std;

class Solution {
public:
	int search(vector<int>& nums, int target) {
		int begin = 0;
		int end = nums.size() - 1;

		while (begin <= end){

			int mid = (begin + end) / 2;

			if (target == nums[mid]) {
				return mid;
			}

			else if (target < nums[mid]) {

				if (nums[begin] < nums[mid]) {
					if (target >= nums[begin]) {
						end = mid - 1;
					}
					else {
						begin = mid + 1; //这边画个图就很理解啦
					}
				}

				else if (nums[begin] > nums[mid]) { //这一步前面还有个条件就是target<nums[mid]
					end = mid - 1;
				}
				else if (nums[begin] == nums[mid]) {
					begin = mid + 1;
				}
			}

			else if (target > nums[mid]) {

				if (nums[begin] < nums[mid]) {

					begin = mid + 1;
				}
				else if (nums[begin] > nums[mid]) {

					if (target >= nums[begin]) {
						end = mid - 1;
					}

					else {
						begin = mid + 1;
					}
				}
				else if (nums[begin] == nums[mid]) {
					begin = mid + 1;
				}
			}
		}
			return -1;
	}
};

int main() {
	int test[] = { 9,12,15,20,1,3,6,7 };
	vector<int> nums;
	Solution solve;
	for (int i = 0; i < 8; i++) {
		nums.push_back(test[i]);
	}
	for (int i = 0; i < 22; i++) {
		printf(" %d :%d \n", i, solve.search(nums, i));
	}
	system("pause");
	return 0;
}

效果图
在这里插入图片描述


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值