分治补充题目

分治补充题目

  1. 区间最大子段和
    • 当然可以使用动态规划,复杂度 O ( n ) O(n) O(n) d p [ i ] dp[i] dp[i] 表示以 a [ i ] a[i] a[i] 为结尾的最长子段
      d p [ i ] = max ⁡ ( d p [ i − 1 ] + a [ i ] , a [ i ] ) dp[i]=\max(dp[i-1]+a[i],a[i]) dp[i]=max(dp[i1]+a[i],a[i])

    • 但是这里我们考虑分治的想法,对于一段区间 [ l , r ] [l,r] [l,r] , 考虑 m i d = ( l + r ) / 2 mid=(l+r)/2 mid=(l+r)/2 ,该区间被分为左右两段, [ l , m i d ] , [ m i d + 1 , r ] [l,mid],[mid+1,r] [l,mid],[mid+1,r] ,总区间的最大子段和只有三种情况,左、右、跨越两段。问题就可以转化为与课上讲的平面最近点对类似的子问题模式。分别在左右就是两个完全相同的子问题,直接递归;跨越中间的部分,则由左半段从右端开始向左的最大子段和右半段从左端开始向右的最大子段

    • 考虑复杂度

      T ( n ) = 2 ∗ T ( n 2 ) + L ( n 2 ) + R ( n 2 ) L ( n ) = L ( n 2 ) + L ( n 2 ) + O ( n ) \begin{aligned} T(n)&=2*T\left(\frac{n}{2}\right)+L\left(\frac{n}{2}\right)+R\left(\frac{n}{2}\right)\\ L(n)&=L\left(\frac{n}{2}\right)+L\left(\frac{n}{2}\right)+O(n) \end{aligned} T(n)L(n)=2T(2n)+L(2n)+R(2n)=L(2n)+L(2n)+O(n)

      在这种情况下,由主定理容易得出 L ( n ) = R ( n ) = Θ ( n l o g n ) ,   T ( n ) = O ( n log ⁡ 2 n ) L(n)=R(n)=\Theta(nlogn),\ T(n)=O(n\log^2 n) L(n)=R(n)=Θ(nlogn), T(n)=O(nlog2n)

    • 这里的 O ( n ) O(n) O(n) 可以通过提前 O ( n ) O(n) O(n) 预处理区间的前缀和降低为 O ( 1 ) O(1) O(1) ,这样 L ( n ) = O ( n ) ,   T ( n ) = O ( n ) + O ( n log ⁡ n ) L(n)=O( n),\ T(n)=O(n)+O(n\log n) L(n)=O(n), T(n)=O(n)+O(nlogn) ,看似复杂度甚至还不如动态规划,但当我们可以结合线段树等数据结构 O ( log ⁡ n ) O(\log n) O(logn) 动态维护区间前缀和的情况下,我们就能在总复杂度 O ( m log ⁡ n ) O(m\log n) O(mlogn) 的情况下动态的维护区间最大子段和,而这是传统动态规划做不到的

  2. 漂亮数组
    • 给定 n n n ,若一个1到n的排列满足 ∀ i , j \forall i,j i,j 满足不 ∃ k   ( i < k < j ) \exist k\ (i<k<j) k (i<k<j) ,满足 a [ i ] + a [ j ] = 2 ∗ a [ k ] a[i]+a[j]=2*a[k] a[i]+a[j]=2a[k] ,那么这个数组是漂亮的。现在给定n,假设漂亮数组存在,求出一个合法的漂亮数组。

    • 性质:若 [ a 1 , a 2 , ⋯   , a n ] [a_1,a_2,\cdots,a_n] [a1,a2,,an] 是漂亮的,则 [ k a 1 + b , k a 2 + b , ⋯   , k a n + b ] [ka_1+b,ka_2+b,\cdots,ka_n+b] [ka1+b,ka2+b,,kan+b] 也是漂亮的。证明利用反证是容易的。

    • 构造思路: 将数组分成左右两部分,分别求出一个漂亮的数组,然后将它们进行变换,使得不存在满足下面条件的三元组:

      A [ m ] ∗ 2 = A [ i ] + A [ j ]   ,   i < m < j A [ m ] ∗ 2 = A [ i ] + A [ j ]\ ,\ i < m < j A[m]2=A[i]+A[j] , i<m<j
      A [ i ] A[i] A[i] 来自左半部分, A [ j ] A[j] A[j] 来自右半部分

      A [ m ] ∗ 2 = A [ i ] + A [ j ] A[m]*2=A[i]+A[j] A[m]2=A[i]+A[j] 的左侧是一个偶数,右侧的两个元素分别来自两个部分,想要保证 A [ i ] + A [ j ] A[i]+A[j] A[i]+A[j] 不为偶数,只要一奇一偶即可,一个直观的想法就是把奇数、偶数分别放在两侧。

      对于一个 { 1 , 2 , ⋯   , n } \{1,2,\cdots,n\} {1,2,,n} 的排列,左半部分包含 ⌊ ( n + 1 ) / 2 ⌋ ⌊(n+1)/2⌋ (n+1)/2 个奇数,右半部分含 ⌊ n / 2 ⌋ \lfloor n/2\rfloor n/2个偶数

      左半部分进行 k = 1 / 2 , b = 1 / 2 k=1/2,b=1/2 k=1/2,b=1/2 的变换,右半部分进行 k = 1 / 2 k=1/2 k=1/2 的变换,这样就变成了同样的子问题,分治解决

  3. 多数元素
    • 给定一个大小为 n n n 的数组,找到其中的多数元素。多数元素是指在数组中出现次数大于 $ \lfloor n/2 \rfloor$ 的元素(假设多数元素一定存在)。

    • 将数组拆分为左右两半,分以下三种情况:

      • 只有一个数,显然为区间众数
      • 左右多数元素相同,则整段区间的多数元素必然也是这个数
      • 左右多数元素不同,遍历区间比较这两个“多数元素”的出现次数
    • 复杂度: T ( n ) = 2 T ( n / 2 ) + O ( n ) T(n)=2T(n/2)+O(n) T(n)=2T(n/2)+O(n) ,由主定理容易推出 T ( n ) = Θ ( n log ⁡ n ) T(n)=\Theta(n\log n) T(n)=Θ(nlogn)

    • 但其实分治并不是最优的解法,考虑 Boyer-Moore 投票算法

      • 我们维护一个候选众数 candidate 和它出现的次数 count。初始时 candidate 可以为任意值,count 为 0;

      • 我们遍历数组中的所有元素,对于每个元素 x,在判断 x 之前,如果 count 的值为 0,我们先将 x 的值赋予 candidate,随后我们判断 x:

        如果 x 与 candidate 相等,那么计数器 count 的值增加 1

        如果 x 与 candidate 不等,那么计数器 count 的值减少 1

      • 遍历结束后,candidate即为多数元素

    • 原理:不妨假设整个数组的众数记做a,则最初的数组中a的数量大于其余所有数。当采用count计数的时候有两种情况:

      1)假设 candidate 等于a,则当 count 从1变为0的过程,此区间内a的数量等于其余数的数量,因此以 count=0 为分界线,数组右端部分的众数仍然为a

      2)假设 candidate 不等于a,则当 count 从1变为0的过程, 此区间内a的数量小于等于其余数的数量,因此以 count=0 为分界线,数组右端部分的众数仍然为a

    • 时间复杂度 O ( n ) O(n) O(n) ,空间复杂度 O ( 1 ) O(1) O(1)

  4. 如果还有时间:啤酒瓶问题

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
毕业设计,基于SpringBoot+Vue+MySQL开发的公寓报修管理系统,源码+数据库+毕业论文+视频演示 现代经济快节奏发展以及不断完善升级的信息化技术,让传统数据信息的管理升级为软件存储,归纳,集中处理数据信息的管理方式。本公寓报修管理系统就是在这样的大环境下诞生,其可以帮助管理者在短时间内处理完毕庞大的数据信息,使用这种软件工具可以帮助管理人员提高事务处理效率,达到事半功倍的效果。此公寓报修管理系统利用当下成熟完善的Spring Boot框架,使用跨平台的可开发大型商业网站的Java语言,以及最受欢迎的RDBMS应用软件之一的MySQL数据库进行程序开发。公寓报修管理系统有管理员,住户,维修人员。管理员可以管理住户信息和维修人员信息,可以审核维修人员的请假信息,住户可以申请维修,可以对维修结果评价,维修人员负责住户提交的维修信息,也可以请假。公寓报修管理系统的开发根据操作人员需要设计的界面简洁美观,在功能模块布局上跟同类型网站保持一致,程序在实现基本要求功能时,也为数据信息面临的安全问题提供了一些实用的解决方案。可以说该程序在帮助管理者高效率地处理工作事务的同时,也实现了数据信息的整体化,规范化与自动化。 关键词:公寓报修管理系统;Spring Boot框架;MySQL;自动化;VUE
前序遍历是二叉树遍历的一种方式,在分治策略中,前序遍历按照根节点、左子树、右子树的顺序进行遍历。以下是分治策略题目前序遍历的步骤: 1. 首先,将根节点压入栈中。 2. 循环执行以下步骤直到栈为空: a. 弹出栈顶节点,并将其值添加到结果列表中。 b. 如果栈顶节点的右子树存在,则将右子树压入栈中。 c. 如果栈顶节点的左子树存在,则将左子树压入栈中。 这个解法是非递归的通用解法,按照前序遍历的规则来处理节点。通过维护一个栈,将需要遍历的节点按照先右后左的顺序压入栈中,然后依次弹出栈顶节点,将其值加入结果列表,并将右子树和左子树压入栈中,重复这个过程直到栈为空。 此外,前序遍历还可以使用递归算法来实现。递归算法的思路是先处理根节点,然后递归地处理左子树和右子树。在分治策略中,递归算法可以将大问题分解成小问题,先处理根节点,然后递归地处理左子树和右子树。 总结起来,分治策略题目的前序遍历可以通过非递归通用解法或递归算法来实现。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [【C语言】数据结构-链式二叉树,详解分治递归和层序遍历](https://blog.csdn.net/muxuen/article/details/124212851)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *2* *3* [14 二叉树的前序遍历(Binary Tree Preorder Traversal)](https://blog.csdn.net/SeeDoubleU/article/details/119834420)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值