当前位置: 首页 > news >正文

【CS.AL】算法核心之分治算法:从入门到进阶

文章目录

    • 1. 概述
    • 2. 适用场景
    • 3. 设计步骤
    • 4. 优缺点
    • 5. 典型应用
    • 6. 题目和代码示例
      • 6.1 简单题目:归并排序
      • 6.2 中等题目:最近点对问题
      • 6.3 困难题目:分数背包问题
    • 7. 题目和思路表格
    • 8. 总结
    • References

1000.01.CS.AL.1.4-核心-DivedeToConquerAlgorithm-Created: 2024-06-15.Saturday09:35
在这里插入图片描述

1. 概述

分治算法(Divide and Conquer)是一种重要的算法设计思想,其核心思想是将一个复杂的问题分解为多个相对简单的小问题,通过解决这些小问题再合并其结果,从而得到原问题的解。分治算法的典型特征是递归,常用于求解具有重复子问题性质的问题。

2. 适用场景

分治算法适用于以下场景:

  • 问题可以分解为若干个规模较小且相互独立的子问题。
  • 这些子问题的解可以合并得到原问题的解。
  • 具有最优子结构性质,即子问题的最优解可以合成原问题的最优解。

3. 设计步骤

  1. 分解(Divide):将原问题分解为若干个子问题,这些子问题的结构与原问题相同但规模较小。
  2. 解决(Conquer):递归地解决这些子问题。当子问题的规模足够小时,直接解决。
  3. 合并(Combine):将子问题的解合并,得到原问题的解。

4. 优缺点

  • 优点:分治算法的递归思想使其在解决许多复杂问题时表现出色。具有良好的可扩展性和并行计算的潜力。
  • 缺点:对于某些问题,分治算法可能会引入额外的开销,如递归调用栈和合并步骤的时间复杂度。

5. 典型应用

  • 归并排序(Merge Sort):一种高效的排序算法,利用分治思想将数组分为两半,递归地排序并合并。
  • 快速排序(Quick Sort):另一种高效的排序算法,选择一个基准元素,将数组分为两部分,递归排序。
  • 最近点对问题(Closest Pair Problem):在平面上找到距离最近的两点,分治法可以将时间复杂度降至 O(nlog⁡n)O(n \log n)O(nlogn)。
  • 矩阵乘法(Strassen’s Algorithm):一种用于矩阵乘法的分治算法,降低了时间复杂度。

6. 题目和代码示例

6.1 简单题目:归并排序

题目描述:实现归并排序算法,对给定的数组进行排序。

代码示例

#include <iostream>
#include <vector>// 函数声明
void mergeSort(std::vector<int>& arr, int left, int right);
void merge(std::vector<int>& arr, int left, int mid, int right);int main() {std::vector<int> arr = {38, 27, 43, 3, 9, 82, 10};mergeSort(arr, 0, arr.size() - 1);for (int num : arr) {std::cout << num << " ";}std::cout << std::endl;return 0;
}// 归并排序:递归地将数组分成两半进行排序
void mergeSort(std::vector<int>& arr, int left, int right) {if (left < right) {int mid = left + (right - left) / 2;mergeSort(arr, left, mid);mergeSort(arr, mid + 1, right);merge(arr, left, mid, right);}
}// 合并两个已排序的子数组
void merge(std::vector<int>& arr, int left, int mid, int right) {int n1 = mid - left + 1;int n2 = right - mid;std::vector<int> L(n1), R(n2);for (int i = 0; i < n1; ++i) {L[i] = arr[left + i];}for (int j = 0; j < n2; ++j) {R[j] = arr[mid + 1 + j];}int i = 0, j = 0, k = left;while (i < n1 && j < n2) {if (L[i] <= R[j]) {arr[k] = L[i++];} else {arr[k] = R[j++];}++k;}while (i < n1) {arr[k++] = L[i++];}while (j < n2) {arr[k++] = R[j++];}
}

Others.

def merge_sort(arr):if len(arr) > 1:mid = len(arr) // 2left_half = arr[:mid]right_half = arr[mid:]merge_sort(left_half)merge_sort(right_half)i = j = k = 0while i < len(left_half) and j < len(right_half):if left_half[i] < right_half[j]:arr[k] = left_half[i]i += 1else:arr[k] = right_half[j]j += 1k += 1while i < len(left_half):arr[k] = left_half[i]i += 1k += 1while j < len(right_half):arr[k] = right_half[j]j += 1k += 1# 示例
arr = [38, 27, 43, 3, 9, 82, 10]
merge_sort(arr)
print(arr)  # 输出: [3, 9, 10, 27, 38, 43, 82]

6.2 中等题目:最近点对问题

题目描述:在平面上找到距离最近的两点,时间复杂度为 O(nlog⁡n)。

代码示例

#include <iostream>
#include <vector>
#include <cmath>
#include <algorithm>struct Point {int x, y;
};double dist(const Point& p1, const Point& p2) {return std::sqrt((p1.x - p2.x) * (p1.x - p2.x) + (p1.y - p2.y) * (p1.y - p2.y));
}double closestPair(std::vector<Point>& points, int left, int right) {if (right - left <= 3) {double minDist = std::numeric_limits<double>::infinity();for (int i = left; i < right; ++i) {for (int j = i + 1; j <= right; ++j) {minDist = std::min(minDist, dist(points[i], points[j]));}}return minDist;}int mid = left + (right - left) / 2;double d1 = closestPair(points, left, mid);double d2 = closestPair(points, mid + 1, right);double d = std::min(d1, d2);std::vector<Point> strip;for (int i = left; i <= right; ++i) {if (std::abs(points[i].x - points[mid].x) < d) {strip.push_back(points[i]);}}std::sort(strip.begin(), strip.end(), [](const Point& p1, const Point& p2) {return p1.y < p2.y;});double minDist = d;for (size_t i = 0; i < strip.size(); ++i) {for (size_t j = i + 1; j < strip.size() && (strip[j].y - strip[i].y) < minDist; ++j) {minDist = std::min(minDist, dist(strip[i], strip[j]));}}return minDist;
}int main() {std::vector<Point> points = {{2, 3}, {12, 30}, {40, 50}, {5, 1}, {12, 10}, {3, 4}};std::sort(points.begin(), points.end(), [](const Point& p1, const Point& p2) {return p1.x < p2.x;});std::cout << "最近点对距离: " << closestPair(points, 0, points.size() - 1) << std::endl;return 0;
}

Others.

import mathdef dist(p1, p2):return math.sqrt((p1[0] - p2[0]) ** 2 + (p1[1] - p2[1]) ** 2)def closest_pair(points):def closest_pair_recursive(points):if len(points) <= 3:return min((dist(p1, p2), (p1, p2)) for i, p1 in enumerate(points) for p2 in points[i+1:])[1]mid = len(points) // 2left_half = points[:mid]right_half = points[mid:](d1, pair1) = closest_pair_recursive(left_half)(d2, pair2) = closest_pair_recursive(right_half)d = min(d1, d2)pair = pair1 if d1 < d2 else pair2strip = [p for p in points if abs(p[0] - points[mid][0]) < d]strip.sort(key=lambda p: p[1])for i in range(len(strip)):for j in range(i+1, len(strip)):if strip[j][1] - strip[i][1] >= d:breakd_new = dist(strip[i], strip[j])if d_new < d:d = d_newpair = (strip[i], strip[j])return d, pairpoints.sort(key=lambda p: p[0])return closest_pair_recursive(points)[1]# 示例
points = [(2, 3), (12, 30), (40, 50), (5, 1), (12, 10), (3, 4)]
print(closest_pair(points))  # 输出: ((2, 3), (3, 4))

6.3 困难题目:分数背包问题

题目描述:给定物品的重量和价值,求在背包容量限制下的最大价值,物品可以分割。

代码示例

#include <iostream>
#include <vector>
#include <algorithm>struct Item {double value;double weight;
};double fractionalKnapsack(std::vector<Item>& items, double capacity) {std::sort(items.begin(), items.end(), [](const Item& a, const Item& b) {return (a.value / a.weight) > (b.value / b.weight);});double totalValue = 0;for (const auto& item : items) {if (capacity >= item.weight) {capacity -= item.weight;totalValue += item.value;} else {totalValue += item.value * (capacity / item.weight);break;}}return totalValue;
}int main() {std::vector<Item> items = {{60, 10}, {100, 20}, {120, 30}};double capacity = 50;std::cout << "背包的最大价值: " << fractionalKnapsack(items, capacity) << std::endl;return 0;
}

Others.

def fractional_knapsack(values, weights, capacity):items = list(zip(values, weights))items.sort(key=lambda x: x[0] / x[1], reverse=True)total_value = 0for value, weight in items:if capacity >= weight:capacity -= weighttotal_value += valueelse:total_value += value * (capacity / weight)breakreturn total_value# 示例
values = [60, 100, 120]
weights = [10, 20, 30]
capacity = 50
print(fractional_knapsack(values, weights, capacity))  # 输出: 240.0

7. 题目和思路表格

序号题目题目描述分治策略代码实现
1归并排序对给定的数组进行排序递归地将数组分成两半进行排序代码
2最近点对问题找到距离最近的两点将点集合递归地分成两半代码
3分数背包问题求在背包容量限制下的最大价值每次选择单位重量价值最高的物品代码
4快速排序高效排序算法选择一个基准元素,将数组分为两部分,递归排序代码
5矩阵乘法用于矩阵乘法将矩阵分成更小的子矩阵,递归计算-
6求逆序对数量统计数组中的逆序对个数使用分治法将数组分成两半,递归统计逆序对-
7最大子序和找出最大和的连续子序列将序列递归地分成两半,合并子序列的结果-
8大整数乘法实现高效的大整数乘法使用Karatsuba算法,将大整数分成两部分进行递归计算-
9二维平面上的最近点对在平面上找到距离最近的两点将点集合递归地分成两半,合并结果-
10棋盘覆盖问题用L型骨牌覆盖2^n * 2^n的棋盘将棋盘递归地分成四部分,覆盖部分棋盘-

8. 总结

分治算法是一种强大的算法设计思想,能够高效地解决许多复杂的问题。通过将问题分解为更小的子问题,分治算法不仅能够降低时间复杂度,还具有良好的可扩展性。在实际应用中,理解和掌握分治算法的思想和典型应用,对于解决各种问题具有重要意义。通过本文的例子和思路,相信读者能够深入理解分治算法的关键概念,并灵活应用于实际问题中。

References

相关文章:

【CS.AL】算法核心之分治算法:从入门到进阶

文章目录 1. 概述2. 适用场景3. 设计步骤4. 优缺点5. 典型应用6. 题目和代码示例6.1 简单题目&#xff1a;归并排序6.2 中等题目&#xff1a;最近点对问题6.3 困难题目&#xff1a;分数背包问题 7. 题目和思路表格8. 总结References 1000.01.CS.AL.1.4-核心-DivedeToConquerAlg…...

leetcode刷题记录:hot100强化训练2:二叉树+图论

二叉树 36. 二叉树的中序遍历 递归就不写了&#xff0c;写一下迭代法 class Solution(object):def inorderTraversal(self, root):""":type root: TreeNode:rtype: List[int]"""if not root:return res []cur rootstack []while cur or st…...

湘潭大学信息与网络安全复习笔记2(总览)

前面的实验和作业反正已经结束了&#xff0c;现在就是集中火力把剩下的内容复习一遍&#xff0c;这一篇博客的内容主要是参考教学大纲和教学日历 文章目录 教学日历教学大纲 教学日历 总共 12 次课&#xff0c;第一次课是概述&#xff0c;第二次和第三次课是密码学基础&#x…...

C语言:头歌使用函数找出数组中的最大值

任务描述 本关任务&#xff1a;本题要求实现一个找出整型数组中最大值的函数。 函数接口定义&#xff1a; int FindArrayMax( int a[], int n ); 其中a是用户传入的数组&#xff0c;n是数组a中元素的个数。函数返回数组a中的最大值。 主程序样例: #include <stdio.h>#…...

【技巧】Leetcode 191. 位1的个数【简单】

位1的个数 编写一个函数&#xff0c;输入是一个无符号整数&#xff08;以二进制串的形式&#xff09;&#xff0c;返回其二进制表达式中 设置位 的个数&#xff08;也被称为汉明重量&#xff09;。 示例 1&#xff1a; 输入&#xff1a;n 11 输出&#xff1a;3 解释&#x…...

【Pandas驯化-02】pd.read_csv读取中文出现error解决方法

【Pandas】驯化-02pd.read_csv读取中文出现error解决方法 本次修炼方法请往下查看 &#x1f308; 欢迎莅临我的个人主页 &#x1f448;这里是我工作、学习、实践 IT领域、真诚分享 踩坑集合&#xff0c;智慧小天地&#xff01; &#x1f387; 相关内容文档获取 微信公众号 &…...

linux下C语言如何操作文件(三)

我们继续介绍file_util.c中的函数: bool create_dir(const char* path):创建目录,根据给定的path创建目录,成功返回true,否则返回false。如果有父目录不存在,该函数不会创建。 /*** 创建目录* @param path 目录路径* @return true 创建成功,false 创建失败*/ bool cre…...

6.14作业

使用手动连接&#xff0c;将登录框中的取消按钮使用第二中连接方式&#xff0c;右击转到槽&#xff0c;在该槽函数中&#xff0c;调用关闭函数 将登录按钮使用qt4版本的连接到自定义的槽函数中&#xff0c;在槽函数中判断ui界面上输入的账号是否为"admin"&#xff0…...

MySQL数据库管理(一)

目录 1.MySQL数据库管理 1.1 常用的数据类型​编辑 1.2 char和varchar区别 2. 增删改查命令操作 2.1 查看数据库结构 2.2 SQL语言 2.3 创建及删除数据库和表 2.4 管理表中的数据记录 2.5 修改表名和表结构 3.MySQL的6大约束属性 1.MySQL数据库管理 1.1 常用的数据类…...

Kafka使用教程和案例详解

Kafka 使用教程和案例详解 Kafka 使用教程和案例详解1. Kafka 基本概念1.1 Kafka 是什么?1.2 核心组件2. Kafka 安装与配置2.1 安装 Kafka使用包管理器(如 yum)安装使用 Docker 安装2.2 配置 Kafka2.3 启动 Kafka3. Kafka 使用教程3.1 创建主题3.2 生产消息3.3 消费消息3.4 …...

TGI模型- 同期群-评论文本

用户偏好分析 TGI 1.1 用户偏好分析介绍 要分析的目标&#xff0c;在目标群体中的均值 和 全部群体里的均值进行比较&#xff0c; 差的越多说明 目标群体偏好越明显 TGI&#xff08;Target Group Index&#xff0c;目标群体指数&#xff09;用于反映目标群体在特定研究范围内…...

ESP32 BLE学习(0) — 基础架构

前言 &#xff08;1&#xff09;学习本文之前&#xff0c;需要先了解一下蓝牙的基本概念&#xff1a;BLE学习笔记&#xff08;0.0&#xff09; —— 基础概念&#xff08;0&#xff09; &#xff08;2&#xff09; 学习一款芯片的蓝牙肯定需要先简单了解一下该芯片的体系结构&a…...

【JAVA】Java中Spring Boot如何设置全局的BusinessException

文章目录 前言一、函数解释二、代码实现三、总结 前言 在Java应用开发中&#xff0c;我们常常需要读取配置文件。Spring Boot提供了一种方便的方式来读取配置。在本文中&#xff0c;我们将探讨如何在Spring Boot中使用Value和ConfigurationProperties注解来读取配置。 一、函数…...

pdf.js实现web h5预览pdf文件(兼容低版本浏览器)

注意 使用的是pdf.js 版本为 v2.16.105。因为新版本 兼容性不太好&#xff0c;部分手机预览不了&#xff0c;所以采用v2版本。 相关依赖 "canvas": "^2.11.2", "pdfjs-dist": "^2.16.105", "core-js-pure": "^3.37.…...

SSID简介

一、 SSID 概念定义 SSID&#xff08;Service Set Identifier&#xff09;即服务集标识符。它是无线网络中的一个重要标识&#xff0c;用于区分不同的无线网络。 相当于无线网络的名称&#xff0c;用于区分不同的无线网络。用户在众多可用网络中识别和选择特定网络的依据。通…...

PS通过GTX实现SFP网络通信1

将 PS ENET1 的 GMII 接口和 MDIO 接口 通过 EMIO 方 式引出。在 PL 端将引出的 GMII 接口和 MDIO 接口与 IP 核 1G/2.5G Ethernet PCS/PMA or SGMII 连接&#xff0c; 1G/2.5G Ethernet PCS/PMA or SGMII 通过高速串行收发器 GTX 与 MIZ7035/7100 开发…...

前端面试项目细节重难点(已工作|做分享)(九)

面试官&#xff1a;请你讲讲你在工作中如何开发一个新需求&#xff0c;你的整个开发过程是什么样的&#xff1f; 答&#xff1a;仔细想想&#xff0c;我开发新需求的过程如下&#xff1a; &#xff08;1&#xff09;第一步&#xff1a;理解需求文档&#xff1a; 首先&#x…...

区间预测 | Matlab实现BP-ABKDE的BP神经网络自适应带宽核密度估计多变量回归区间预测

区间预测 | Matlab实现BP-ABKDE的BP神经网络自适应带宽核密度估计多变量回归区间预测 目录 区间预测 | Matlab实现BP-ABKDE的BP神经网络自适应带宽核密度估计多变量回归区间预测效果一览基本介绍程序设计参考资料 效果一览 基本介绍 1.Matlab实现BP-ABKDE的BP神经网络自适应带…...

抢占人工智能行业红利,前阿里巴巴产品专家带你15天入门AI产品经理

前言 当互联网行业巨头纷纷布局人工智能&#xff0c;国家将人工智能上升为国家战略&#xff0c;藤校核心课程涉足人工智能…人工智能领域蕴含着巨大潜力&#xff0c;早已成为业内共识。 面对极大的行业空缺&#xff0c;不少人都希望能抢占行业红利期&#xff0c;进入AI领域。…...

MEMS:Lecture 16 Gyros

陀螺仪原理 A classic spinning gyroscope measures the rotation rate by utilizing the conservation of angular momentum. 经典旋转陀螺仪通过利用角动量守恒来测量旋转速率。 Coriolis Effect and Coriolis Force 科里奥利效应是一种出现在旋转参考系中的现象。它描述了…...

英雄联盟智能辅助套件:重新定义MOBA游戏体验的开源工具集

英雄联盟智能辅助套件&#xff1a;重新定义MOBA游戏体验的开源工具集 【免费下载链接】League-Toolkit 兴趣使然的、简单易用的英雄联盟工具集。支持战绩查询、自动秒选等功能。基于 LCU API。 项目地址: https://gitcode.com/gh_mirrors/le/League-Toolkit League-Tool…...

2026微软SDE LeetCode高频题:208道,按频度排序,含备考建议

2026微软SDE LeetCode高频题&#xff1a;208道&#xff0c;按频度排序&#xff0c;含备考建议 微软SDE的LeetCode面试题&#xff0c;第一名不是反转链表&#xff0c;不是LRU缓存&#xff0c;而是—— 215. 数组中的第K个最大元素&#xff0c;出现14次。 我整理了基于真实面经…...

如何去选择品质优秀的段码屏厂家

在现代电子产品中&#xff0c;LCD液晶段码屏的应用越来越广泛。选择一家优质的厂家不仅能保证产品质量&#xff0c;还能提供高效的服务。本文将为您推荐十家在LCD液晶段码屏领域表现突出的厂家&#xff0c;帮助您做出明智的选择。1. 杭州斡能电子有限公司杭州斡能电子有限公司&…...

DanKoe 视频笔记:生活哲学:理解生活的三个阶段

在本节课中&#xff0c;我们将学习一个关于个人成长与生活节奏的框架。通过理解“强度”、“一致性”和“好奇心”这三个循环往复的阶段&#xff0c;你可以更好地定位自己当前的状态&#xff0c;并学会顺应而非对抗生活的自然周期&#xff0c;从而减少迷茫&#xff0c;更有效地…...

ChezScheme测试性能优化:从53分钟到8分钟的效率跃迁

ChezScheme测试性能优化&#xff1a;从53分钟到8分钟的效率跃迁 【免费下载链接】ChezScheme Chez Scheme 项目地址: https://gitcode.com/gh_mirrors/ch/ChezScheme 一、痛点分析&#xff1a;串行测试的性能瓶颈 识别测试效率问题 在软件开发迭代过程中&#xff0c;…...

从零到数据分析:用ClickHouse+DBeaver在Windows上复现一个电商用户行为查询

从零构建电商数据分析平台&#xff1a;Windows下ClickHouse与DBeaver实战指南 1. 为什么选择ClickHouse进行电商行为分析&#xff1f; 去年双十一期间&#xff0c;某头部电商平台通过实时分析用户点击流数据&#xff0c;在活动开始后30分钟内就调整了首页推荐策略&#xff0c…...

计算机毕业设计springboot校园外卖系统 基于Spring Boot的高校餐饮配送服务平台 Spring Boot框架下的校园在线订餐与配送管理系统

计算机毕业设计springboot校园外卖系统n322b9 &#xff08;配套有源码 程序 mysql数据库 论文&#xff09; 本套源码可以在文本联xi,先看具体系统功能演示视频领取&#xff0c;可分享源码参考。随着互联网技术的日益成熟和普及&#xff0c;网络已经深度融入人们的日常生活&…...

解锁毕业论文新姿势:书匠策AI,你的学术“超级外挂”!

在学术的征途上&#xff0c;毕业论文无疑是每位学子必须跨越的一道重要关卡。它不仅是对你大学四年学习成果的全面检验&#xff0c;更是你迈向学术殿堂或职场的重要敲门砖。然而&#xff0c;面对堆积如山的资料、错综复杂的逻辑结构&#xff0c;以及那令人头疼的格式要求&#…...

英雄联盟智能工具集:3个颠覆性功能重塑你的游戏体验

英雄联盟智能工具集&#xff1a;3个颠覆性功能重塑你的游戏体验 【免费下载链接】League-Toolkit 兴趣使然的、简单易用的英雄联盟工具集。支持战绩查询、自动秒选等功能。基于 LCU API。 项目地址: https://gitcode.com/gh_mirrors/le/League-Toolkit 作为英雄联盟玩家…...

避开C盘爆满!保姆级教程:在D盘安装Unity 2023.2f1c1和VS2022社区版

避开C盘爆满&#xff01;保姆级教程&#xff1a;在D盘安装Unity 2023.2f1c1和VS2022社区版 对于刚接触游戏开发的新手来说&#xff0c;安装Unity和Visual Studio往往是遇到的第一个"拦路虎"。更让人头疼的是&#xff0c;这两个"重量级"开发工具默认都会占…...