算法与设计分析作业(分治)

分治 Divide and Conquer 局部最小值 local optimal 棋盘问题 问题描述: Suppose now that you're given an  n × n grid graph $G$. (An n × n graph is just the adjacency graph of an $n \times n$ chessboard. To be completely precise, it is a graph whose node set is the 阅读详情

算法与设计分析作业


 

2 Divide and Conquer

Find the kth largest element in an unsorted array. Note that it is the kth largest element in the sorted order, not the kth distinct element.
For example, Given [3, 2 ,1, 5, 6, 4] and k = 2, return 5.

problem-solving ideas

借鉴快速排序的思想,快排每一次排序之后可以确定一个元素的位置,该元素的左边均小于该元素,右边均大于该元素,因此可以用该元素的位置与k比较,来确定第k大的元素在当前数组那个范围内,然后递归。从而省去另一部分的查找。

Pseudo-code
function findKthLargest(A,k,s,e){
    随机选取一个元素A[j]作为分界点
     for i=s to e do
       if A[i] < A[j]
         将A[i]放在A[j]的右边
       end if
       if A[i] > A[j]
         将A[i]放在A[j]的左边
       end if
     end for
    A[j]当前在A数组中的位置为w,数组长度为length(数组从0开始)
    if k == length-w
      返回 A[j]
    else if k> length-w
      返回 findKthLargest(A,k,s,w);
    else 
      返回 findKthLargest(A,k,w,e)
    end if   
}
Subproblem reduction graph

寻找第k大元素

Prove the correctness

根据快排的性质,每一次的递归都可以确定一个元素的位置,且该元素左边的元素均小于该元素值,右边的元素均大于该元素值,而我们要找的是第k大的元素,通过两者位置的比较,我们一定能确定第k大元素在哪一个范围内,随着递归深入范围逐渐缩小,因此最后一定能找到第k大的元素。

#### The complexity of your algorithm

最好的情况:每次挑选的元素都能将数组平均分成左右相等两边,则 T(n) =T(n/2)+cn。根据公式T(n)=O(n),所以时间复杂度为O(n)。

最坏的情况:每次挑选的元素都将数组分在一边(即挑选的都是最大值或最小值),则T(n)=T(n-1)+cn。T(n)=O(n2).

平均情况应该接近于最好的情况。


 

3 Divide and Conquer

Consider an n-node complete binary tree T, where n = 2d −1 for some d. Each node v of T is labeled with a real number xv. You may assume that the real numbers labeling the nodes are all distinct. A node v of T is a local minimum if the label xv is less than the label xw for all nodes w that are joined to v by an edge.
You are given such a complete binary tree T, but the labeling is only specified in the following implicit way: for each node v, you can determine the value xv by probing the node v. Show how to find a local minimum of T using only O(logn) probes to the nodes of T.

problem-solving ideas

​ 问题的关键在于如何分治把范围缩小,且范围内一定要有局部最小值。因此递归的子树的要求是,递归子树的根结点的值要小于父结点的值,这样的子树一定有局部最小值,且范围被缩小。

Pseudo-code
function findLocalMinimum(T){
    if T的值小于左右子树根结点的值,所有子树若为空则算小于
        返回 T->data
    else if T的值大于左子树根结点的值小于右子树根结点的值
        返回 findLocalMinimum(T的右子树)
    else if T的值小于左子树根结点的值大于右子树根结点的值
        返回 findLocalMinimum(T的左子树)
    else
        返回 findLocalMinimum(T的左子树或T的右子树)
    end if
}
Subproblem reduction graph

完全二叉树的局部最小值

Prove the correctness

任何一棵完全二叉树都有局部最小值,完全二叉树的子树仍然是完全二叉树。对于任何一棵树T,如果T的值小于左右子树的根节点,则T的值就是局部最小值,否则T的值一定大于其中某一棵子树,由于该子树的父结点大于该子树根结点的值,因此父结点不用考虑,且该子树一定有局部最小值。

The complexity of your algorithm

分析算法可得 T(n) =T(n/2)+c。根据公式T(n)=O(log n),所以时间复杂度为O(log n)。


 

6 Divide and Conquer

Recall the problem of finding the number of inversions. As in the course, we are given a sequence of n numbers a1,··· ,an, which we assume are all distinct, and we difine an inversion to be a pair i < j such that ai > aj.
We motivated the problem of counting inversions as a good measure of how different two orderings are. However, one might feel that this measure is too sensitive. Let’s call a pair a significant inversion if i < j and ai > 3aj. Given an O(nlogn) algorithm to count the number of significant inversions between two orderings.

problem-solving ideas

​ 只需在普通的寻找逆序对中改一些步骤。依旧需要归并排序,在归并排序的过程中声明j1,j2(普通的寻找逆序对只声明j),j1用来归并排序。j2来表示是否当前的指向的元素是否已经用来记过数(j2一开始指向A[mid+1],每当A[i]>3*A[j2]就记逆序对数,并且j2向后移动,表明已经被记过数了)。

Pseudo-code
function sortAndCount(A,s,e){
    if s < e
        mid = (s+e)/2
        count1 = sortAndCount(A,s,mid)
        count2 = sortAndCount(A,mid+1,e)
        返回 count1+count2+mergeAndCount(A,s,mid,e)
     else
        返回 0
     end if
}
function mergeAndCount(A,start,mid,end){
    i=start,j1=mid+1,j2=mid+1,count=0,k=0
    建立数组temp临时存放排序好的数组元素
    while i<=mid and j1<=end
        if A[i]<A[j1]
            if A[i]>3*A[j2]
                count += mid - i + 1
                j2++
             else 
                temp[k++]=A[i++]
             end if
         else 
            temp[k++]=A[j1++]
         end if
    end while
    while i<=mid
        if(j2<=end)
            if A[i]>3*A[j2]
                count += mid - i + 1
                j2++
             else 
                temp[k++]=A[i++]
             end if
         else
            temp[k++]=A[i++]
         end if
    end while
    while j1<end
        temp[k++]=A[j1++]
    end while
    将temp数组再重新赋给A
    返回 count
}
Subproblem reduction graph

​ 寻找逆序对

Prove the correctness

普通的寻找逆序对的方法的正确性已经被证明,这里只是根据题意修改了计数的方法,因此该方法也应该是正确的。

The complexity of your algorithm

时间复杂度和普通的求逆序对算法一样为O(nlogn)。T(n)=2*T(n/2)+cn 推出 T(n)=O(nlogn)。


 

10 Divide and Conquer

Implement the Strassen algorithm algorithm for MatrixMultiplication problem in your favourite language, and compare the performance with grade-school method.

C++ Code
//矩阵乘法(分治)
#include <STDLIB.H>
#include <IOSTREAM>
#include <time.h>
using namespace std;

void print(int **M, int n)
{

    int i;
    int j;
    for (i = 0; i < n; i++)
    {
        for (j = 0; j < n; j++)
        {
            cout << M[i][j] << " ";
        }
        cout << endl;
    }
}

void init(int ** &M, int n)
{
    M = new int *[n];
    int i;
    for (i = 0; i < n; i++)
    {
        M[i] = new int[n];
    }
}

void add(int **&A, int **&B, int n, int **&C) //A+B=C
{
    int i;
    int j;
    for (i = 0; i < n; i++)
    {
        for (j = 0; j < n; j
算法设计与分析作业六之选第k小元素:特定分治策略 一、问题描述: 设S是n个元素的集合,从S中选取第k小的元素,其中1≤k≤n。这里的第k小的元素是指,当S按从小到大排好序后,排在第k个位置的元素。 采用二分归并排序,然后选择第k小元素。 二、算法核心步骤(伪代码)及图解: 伪代码: Select(S,k) 输入:n个数的数组S,正整数k; 输出:S中的第k小元素; 1.将S划分为5个一组,共[n/5]个组; 2.每组找一个中位数,把这些中位数放... 阅读详情

相关推荐

算法分析与设计实践 - 作业5 - 分治法解最近对问题

1 .问题 课本149页最近对问题 2.解析 3.设计 #include <stdio.h> 4.分析 算法复杂度 5.码源 源码地址: https://github.com/chaoxing0910/ex5

f1149446855的博客 468

中科院卜东波算法分析与设计答案

卜东波老师布置的作业,里面有很多讲解,希望同学下下来看看

AMG8833红外测温实战:在STM32F103上做个简易人体感应与温度报警器

本文详细介绍了如何在STM32F103上使用AMG8833红外测温传感器构建人体感应与温度报警系统。通过硬件连接方案、驱动代码开发、人体检测算法实现及报警系统设计,展示了如何利用8x8红外温度矩阵实现智能监测功能。文章包含实用的初始化流程、温度数据读取优化和低功耗策略,为创客项目提供完整解决方案。

weixin_33725239的博客 392

一文入门Qwen-Agent【附实战代码】

Qwen-Agent 是一个开源框架,用于开发基于 Qwen 模型的 AI 智能体应用,一文带你入门使用

m0_55303420的博客 1873

莫比乌斯反演

本文从算法竞赛和数论角度出发,系统介绍了狄利克雷卷积与莫比乌斯反演的核心概念。首先定义了数论函数及其基本性质,重点阐述了狄利克雷卷积的代数结构(交换环)和关键恒等式(如μ*1=ε)。随后通过卷积视角简化了莫比乌斯反演的证明过程。最后将理论提升至抽象代数层面,揭示这些数论工具本质上是偏序集关联代数在整除关系下的特例,其中莫比乌斯函数对应Zeta函数的逆元。全文展现了数学概念从具体到抽象的升华过程,为理解这些工具提供了更深刻的代数视角。

aichitang2024的博客 391

四款办公Agent实测对比:WorkBuddy、千问办公、库库AI、豆包工作怎么选

AI Agent是一种能感知环境、自主决策并执行动作的智能系统,其核心在于工具调用、状态管理与错误恢复构成的执行闭环。在办公场景中,任务边界清晰、容错率高、重复性强,使Agent成为最容易落地的方向。通过调用本地文件、脚本或办公套件,Agent能自动完成文件批量处理、文档摘要、会议纪要等重复劳动,显著提升工作效率。目前WorkBuddy、千问办公、库库AI、豆包工作等产品分别从本地操作、办公套件嵌入、知识处理、轻量助手等路线切入,用户可根据自身场景选择。

weixin_29052717的博客 519

从零构建:用Arduino和MCP2515模块搭建你的第一个CAN Bus网络

本文详细介绍了如何使用Arduino和MCP2515模块从零搭建CAN Bus网络,实现温湿度数据的传输与显示。涵盖硬件连接、软件配置、发送端与接收端代码实现,以及系统调试和进阶应用,帮助初学者快速掌握CAN总线通信技术。

d6e7f8的博客 831

vscode使用continue插件连接LM studio的模型

本文详细介绍了如何使用VSCode的Continue插件连接LM Studio模型。主要步骤包括:在LM Studio中加载模型并设置相关参数,启动API服务,修改Continue配置文件以集成LM Studio模型,并进行测试以验证连接是否成功。通过这些步骤,用户可以将LM Studio中的预训练模型与VSCode的Continue插件无缝对接,实现高效的自然语言处理和编程辅助功能。

weixin_43590837的博客 8626

3D深度饼图的QT实现

首先,我们需要创建一个QT项目并创建一个窗口,用于显示我们的饼图。在QT Creator中,选择创建一个新的QT Widgets应用程序项目,并创建一个新的窗口类。在本文中,我将介绍如何使用QT实现一个3D深度饼图(Pie 3D)的可视化效果。在构造函数中,我们将创建一个饼图(QChartView)并设置饼图的数据。这是一个简单的示例,您可以根据需要自定义和扩展代码来创建更复杂的饼图。现在,我们已经完成了3D深度饼图的QT实现。您将看到一个具有相应数据的3D深度饼图显示在窗口中。3D深度饼图的QT实现。

CodeJolt的博客 277

【unity小技巧】实现FPS射击游戏枪武器随镜头手臂摇摆效果(2025/12/11补充)

如果我们视角移动转向,武器如果不跟着进行摇摆,会感觉我们的动作很生硬,特别是射击类游戏,如下实现武器摇摆这里主要分享两种实现方法,一种是改变武器位置,一种是修改武器旋转想要使用哪种方法都可以,看你自己喜欢,如果是我,我会选择第二种,比较简单,参数也少,而且个人感觉效果也更好,已枪中心做旋转更符合现实。

向宇的博客,专注php/web全栈 unity游戏开发,欢迎大家评论纠错 1470

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

上一篇: LeetCodeOJ——10. Regular Expression Matching
下一篇: 32. Longest Valid Parentheses
King来写代码
博客等级 码龄12年 68粉丝 30原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值