开宗明义:本系列基于小象学院林沐老师课程《面试算法 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;
}
效果图: