创作不易,本篇文章如果帮助到了你,还请点赞 关注支持一下♡>𖥦<)!!
主页专栏有更多知识,如有疑问欢迎大家指正讨论,共同进步!
更多算法分析与设计知识专栏:算法分析🔥
给大家跳段街舞感谢支持!ጿ ኈ ቼ ዽ ጿ ኈ ቼ ዽ ጿ ኈ ቼ ዽ ጿ ኈ ቼ ዽ ጿ ኈ ቼ
目录
- 一、二分搜索问题
- 问题描述
- 算法思想和解题思路
- C++代码
- 二、假币识别问题
- 问题描述
- 算法思想和解题思路
- C++代码
一、二分搜索问题
二分搜索解题框架见:【算法】分治法的基本思想和二分搜索的应用
问题描述
设a[0:n-1]
是已排好序的数组
试改写二分搜索算法,使得当搜索元素x
不在数组a中时,返回小于
的最大元素的位置i
和大于x
的最小元素的位置j
当搜索元素x
在数组a中时,返回x
在数组中的位置,此时i和j
相同
算法思想和解题思路
先将有序数组分成两部分,中间位置mid为基准值
-
若该值等于目标值key,则直接返回
-
若该值大于目标值,则在左半部分进行二分搜索
-
若该值小于目标值,则在右半部分进行二分搜索
循环执行二分搜索,直到左侧low标记大于右侧high标记,跳出循环则为查找失败,此时的begin
就是比x大的最小数组元素下标,end
就是比x小的最大元素数组下标
二分算法运作的核心理念是将数组分割为两部分,然后根据所查找或排序的元素与中间元素的比较结果,将查找或排序的范围缩小一半
C++代码
#include <iostream>
using namespace std;
/*
二分搜索问题:设a[0:n-1]是已排好序的数组。试改写二分搜索算法,
使得当搜索元素x不在数组a中时,返回小于x的最大元素的位置i和大于x的最小元素的位置j;
当搜索元素x在数组a中时,返回x在数组中的位置,此时i和j相同。
*/
void binarySearch(int arr[],int target)
{int length = 7;int left = 0;int right = length - 1;if (target < arr[0]) {cout << "比x大的最小数组元素的下标是0" << endl;cout << "不存在比x小的数组元素" << endl;return;}else if (target > arr[length - 1]) {cout << "不存在比x大的数组元素" << endl;cout << "比x小的最大数组元素的下标是" << right << endl;return;}while (left <= right){int mid = (left + right) / 2;if (arr[mid] == target) {cout << "与x相等的数据元素的下标是" << mid << endl;return;}else if (arr[mid] < target) {left = mid + 1;}else {right = mid - 1;}}cout << "比x大的最小数组元素的下标是" << left << endl;cout << "比x小的最大数组元素的下标是" << right << endl;return ;
}int main()
{int a[] = { 2,3,4,5,6,8,9 };binarySearch(a, 7);binarySearch(a, 4);return 0;
}
二、假币识别问题
问题描述
一个袋子里有n
个硬币,其中一枚是假币,假币和真币外观一模一样,仅凭肉眼无法区分,但是已知假币比真币轻一些
试设计识别假币的分治算法
算法思想和解题思路
先判断当前硬币数量是奇数还是偶数
-
如果硬币数量是偶数,那么我们需要做的是检查这些硬币是否只有两枚。如果是,那么比较这两枚硬币的重量,较轻的那枚就是假币。如果没有只有两枚硬币,那么我们将这些硬币分成两堆,比较这两堆的重量,轻的那堆中会有假币。
-
如果硬币数量是奇数,我们需要做的是取出中间的那枚硬币。然后,将剩余的硬币分成两部分。如果这两部分的重量相等,那么假币就是我们之前取出的中间那枚。如果这两部分的重量不相等,就重复到只有两个硬币比较重量,轻的一个就是假币
分治法将一个问题分解为多个子问题,并递归地解决这些子问题,最后将子问题的解合并为原问题的解
C++代码
#include <iostream>
using namespace std;// 判断硬币是否为假币
bool isfake(int coin[], int n, int i) {for (int j = 0; j < i; j++) {if (coin[j] < coin[i]) {return true;}}for (int j = i + 1; j < n; j++) {if (coin[j] < coin[i]) {return true;}}return false;
}
// 识别假币的分治算法
void search(int coin[], int n) {if (n == 2) {// 当硬币数量为2时,输出重量较轻的硬币 if (coin[0] < coin[1]) {cout << coin[0] << endl;}else {cout << coin[1] << endl;}}else if (n % 2 == 0) {// 当硬币数量为偶数时,将硬币分成两段,并比较两段的平均重量 int mid = n / 2;if (isfake(coin, n, mid)) {search(coin, mid);}else {search(coin + mid, n - mid);}}else {// 当硬币数量为奇数时,去掉中间的硬币,将剩余的硬币分成两段,并比较两段的平均重量 int mid = (n - 1) / 2;if (isfake(coin, n, mid + 1)) {search(coin, mid + 1);}else {search(coin + mid + 1, n - mid - 1);}}
}int main() {int arr[4] = { 2,4,2,5 };search(arr, 4);return 0;
}
大家的点赞、收藏、关注将是我更新的最大动力! 欢迎留言或私信建议或问题。 |
大家的支持和反馈对我来说意义重大,我会继续不断努力提供有价值的内容!如果本文哪里有错误的地方还请大家多多指出(●'◡'●) |