算法设计与分析笔记

1 绪论

算法的由来

算法的定义

算法的表示

算法的分析

渐近分析
T(n)= Θ (g(n))等价于:T(n)=Ω(g(n))且T(n)=O(g(n))

渐近记号名称输入情况情况说明
Θ渐近紧确界
O渐近上界最坏情况确认上界,更具一般性
Ω渐近下界最好情况不常出现,不具普遍性

算法运行时间称为算法的时间复杂度,通常使用渐近记号O表示。

2 分而治之篇

分而治之:一般步骤

  • 分解原问题:原问题分解成多个子问题
  • 解决子问题:递归地解决各个子问题
  • 合并问题解:将结果合并为原问题解

2.1 归并排序

2.2 最大子数组问题

2.3 逆序对计数问题

2.3.1 问题背景:逆序对

逆序对

  • 当 i < j 时A[ i ]>A[ j ]的二元组(A[ i ],A[ j ])

逆序对
例如 1 < 4 且 A[ 1 ]>A[ 4 ]
问题:数组A中有多少逆序对?
答案:五对,{(A[1],A[4]),(A[2],A[4]),(A[2],A[5]),(A[3],A[4]),(A[3],A[5])}

2.3.2 问题定义

形式化定义:逆序对计数问题

输入:

  • 长度为n的数组A[1…n]

输出

  • 数组A[1…n]逆序对的总数,即:
    在这里插入图片描述
蛮力枚举

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
蛮力枚举代码:

//输入:长度为n的数组A[1...n] 
//输出:  数组A[1...n]逆序对的数目sum
sum = 0for(i=1;i<=n;i++){
	for(j=i+1;j<=n;j++){
		if(A[i]>A[j])
			sum++;
	}
}
return sum;

时间复杂度O(n2)

分而治之
算法框架

在这里插入图片描述

在这里插入图片描述

  • 把数组A二分为两个子数组A[1…n/2],A[n/2+1…n]

在这里插入图片描述

  • 递归求解子问题
    • 求解S1 :仅在A[1…n/2]中的逆序对数目
    • 求解S2 :仅在A[n/2+1…n]中的逆序对数目

在这里插入图片描述

  • 合并A[1…n/2]和A[n/2+1…n]的解
    • 求解S3 :跨越子数组的逆序对数目
  • S = S1 + S2 + S3
合并问题解:求解S3

策略一:直接求解

  • 对每个A[ j ] ∈ A[ m+1 … n ],枚举A[ i ] ∈ A[ 1…m ]并统计逆序对数目
  • 求解S3的算法运行时间:O(n2)
  • 分而治之框架的算法运行时间:T(n)=2·T(n/2)+O(n2) → O(n2)
    在这里插入图片描述

    在这里插入图片描述
    逆序对总数:3+4+2+1=10
    直接求解S3的分而治之较蛮力枚举并未提高算法运行时间!

分析导致原因

  • 运行时间受限于跨越子数组的逆序对计数方法
  • 数组的有序性通常有助于提高算法的运行时间
    在这里插入图片描述
    策略二:排序求解
  1. 分别对数组A[1…m] 和 A[ m+1…n ]进行排序
  2. 对于每个A[ j ] ∈A[ m+1…n ],采用二分查找为其在[1…m] 中定位
    由1 和2 可知 运行时间 n 2 \frac{n}{2} 2n log n 2 \frac{n}{2} 2n
  3. A[ j ]在A[1…m]定位点右侧的元素均可与A[ j ]构成逆序对
    在这里插入图片描述

    在这里插入图片描述
  4. 求解S3的算法运行时间:O(n log n)
  5. 分治框架的算法运行时间:T(n)=2T(n/2)+O(n log n) → O(n log2 n)
    排序求解S~3~的分而治之提高了算法运行时间,是否还有优化可能?

算法优化

  • 排序和二分查找均无再优化空间
    子数组排序的运行时间:O(n log n)
    二分查找的运行时间:O(n log n)

致因分析

  • 为将排序过程融入整个算法框架
    如何将排序过程融入整个算法框架?归并排序!

策略三:归并求解

  1. 从左到右扫描有序子数组:A[ i ] ∈ A[ 1…m ], A[ j ] ∈ A[ m+1 …n ]
    • 如果A[ i ] > A[ j ],统计逆序对,j向右移
    • 如果 A[ i ] ≤ A[ j ],i向右移
  2. 利用归并排序框架保证合并后数组的有序性
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    在这里插入图片描述
    S3 = 4+3+2+1=10
    求解3时间复杂度降至O(n)

归并求解代码:MergeCount(A,left,mid,right)

/**
 * 输入:数组A[1...n],数组下标left,mid,right
 *
 * 输出:跨越数组A[left..mid]和 A[mid+1...right]的逆序对数,A[left...right]
 *
*/

void MergCount(int A[], int left, int mid, int right) {
    int _A[left..right] = A[left..righ];
    int S1 = 0, S2 = 0, S3 = 0;
    int i = left, j = mid, k = 0;
    while (i <= mid && j <= right) {
        if (_A[i] <= _A[j]) {
            A[left + k] = _A[i];
            k++;
            i++;
        } else {
            A[left + k] = _A[j];
            S3 = S3 + (mid - i + 1);
            k++;
            j++;
        }
    }
    if (i <= mid) {
        A[k..right] = _A[i..mid]
    } else
        A[k..right] = _A[j..riht]
    return S3,A[left..right];
}

运行实例步骤:
在这里插入图片描述

归并求解:CountInver( A, left, right)

/**
 * 输入:数组A[1..n],数组下标left,right
 * 输出:数组A[left..right]的逆序对数,递增数组A[left..right]
 */
void CountInver(int A[], int left, int right){
    if(left>=right)
        return A[left..right];
    mid = (left+right)/2;     // 分解原问题
    S1 = CountInver(A,left,mid);  //解决子问题
    S2 = CountInver(A,mid+1,right); //解决子问题
    S3 = MergCount(A,left,mid,right); //合并问题解
    S = S1+S2+S3;
    return S,A[left..righ];
}

小结:

算法名称合并求解复杂度时间复杂度
蛮力枚举O(n2)
分而治之+直接计算O(n2)O(n2)
分而治之+排序求解O(n log n)O(n log2 n)
分而治之+归并求解O(n)O(n log2 n)

分治策略关键:合理设计合并求解算法

快速排序

次序选择问题

3 动态规划篇

0-1背包问题

最大子数组为题Ⅱ

最长公共子序列问题

最长公共子串问题

最小编辑距离问题

钢条切割问题

矩阵链乘法问题

4 贪心策略篇

部分背包问题

霍夫曼编码

活动选择问题

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
commons-lang3.3.1.jar、Apache Commons包中的一个,包含了一些数据类型工具类,是java.lang.*的扩展。必须使用的jar包。为JRE5.0+的更好的版本所提供 Jar文件包含的类: META-INF/MANIFEST.MFMETA-INF/LICENSE.txtMETA-INF/NOTICE.txtorg.apache.commons.lang.ArrayUtils.class org.apache.commons.lang.BitField.class org.apache.commons.lang.BooleanUtils.class org.apache.commons.lang.CharEncoding.class org.apache.commons.lang.CharRange.class org.apache.commons.lang.CharSet.class org.apache.commons.lang.CharSetUtils.class org.apache.commons.lang.CharUtils.class org.apache.commons.lang.ClassUtils.class org.apache.commons.lang.Entities$ArrayEntityMap.class org.apache.commons.lang.Entities$BinaryEntityMap.class org.apache.commons.lang.Entities$EntityMap.class org.apache.commons.lang.Entities$HashEntityMap.class org.apache.commons.lang.Entities$LookupEntityMap.class org.apache.commons.lang.Entities$MapIntMap.class org.apache.commons.lang.Entities$PrimitiveEntityMap.class org.apache.commons.lang.Entities$TreeEntityMap.class org.apache.commons.lang.Entities.class org.apache.commons.lang.IllegalClassException.class org.apache.commons.lang.IncompleteArgumentException.class org.apache.commons.lang.IntHashMap$Entry.class org.apache.commons.lang.IntHashMap.class org.apache.commons.lang.LocaleUtils.class org.apache.commons.lang.NotImplementedException.class org.apache.commons.lang.NullArgumentException.class org.apache.commons.lang.NumberRange.class org.apache.commons.lang.NumberUtils.class org.apache.commons.lang.ObjectUtils$Null.class org.apache.commons.lang.ObjectUtils.class org.apache.commons.lang.RandomStringUtils.class org.apache.commons.lang.SerializationException.class org.apache.commons.lang.SerializationUtils.class org.apache.commons.lang.StringEscapeUtils.class org.apache.commons.lang.StringUtils.class org.apache.commons.lang.SystemUtils.class org.apache.commons.lang.UnhandledException.class org.apache.commons.lang.Validate.class org.apache.commons.lang.WordUtils.class org.apache.commons.lang.builder.CompareToBuilder.class org.apache.commons.lang.builder.EqualsBuilder.class org.apache.commons.lang.builder.HashCodeBuilder.class org.apache.commons.lang.builder.ReflectionToStringBuilder$1.class org.apache.commons.lang.builder.ReflectionToStringBuilder.class org.apache.commons.lang.builder.StandardToStringStyle.class org.apache.commons.lang.builder.ToStringBuilder.class org.apache.commons.lang.builder.ToStringStyle$DefaultToStringStyle.class org.apache.commons.lang.builder.ToStringStyle$MultiLineToStringStyle.class org.apache.commons.lang.builder.ToStringStyle$NoFieldNameToStringStyle.class org.apache.commons.lang.builder.ToStringStyle$ShortPrefixToStringStyle.class org.apache.commons.lang.builder.ToStringStyle$SimpleToStringStyle.class org.apache.commons.lang.builder.ToStringStyle.class org.apache.commons.lang.enum.Enum$Entry.class org.apache.commons.lang.enum.Enum.class org.apache.commons.lang.enum.EnumUtils.class org.apache.commons.lang.enum.ValuedEnum.class org.apache.commons.lang.enums.Enum$Entry.class org.apache.commons.lang.enums.Enum.class org.apache.commons.lang.enums.EnumUtils.class org.apache.commons.lang.enums.ValuedEnum.class org.apache.commons.lang.exception.ExceptionUtils.class org.apache.commons.lang.exception.Nestable.class org.apache.commons.lang.exception.NestableDelegate.class org.apache.commons.lang.exception.NestableError.class org.apache.commons.lang.exception.NestableException.class org.apache.commons.lang.exception.NestableRuntimeException.class org.apache.commons.lang.math.DoubleRange.class org.apache.commons.lang.math.FloatRange.class org.apache.commons.lang.math.Fraction.class org.apache.commons.lang.math.IntRange.class org.apache.commons.lang.math.JVMRandom.class org.apache.commons.lang.math.LongRange.class org.apache.commons.lang.math.NumberRange.class org.apache.commons.lang.math.NumberUtils.class org.apache.commons.lang.math.RandomUtils.class org.apache.commons.lang.math.Range.class org.apache.commons.lang.mutable.Mutable.class org.apache.commons.lang.mutable.MutableBoolean.class org.apache.commons.lang.mutable.MutableByte.class org.apache.commons.lang.mutable.MutableDouble.class org.apache.commons.lang.mutable.MutableFloat.class org.apache.commons.lang.mutable.MutableInt.class org.apache.commons.lang.mutable.MutableLong.class org.apache.commons.lang.mutable.MutableObject.class org.apache.commons.lang.mutable.MutableShort.class org.apache.commons.lang.text.CompositeFormat.class org.apache.commons.lang.text.StrBuilder$StrBuilderReader.class org.apache.commons.lang.text.StrBuilder$StrBuilderTokenizer.class org.apache.commons.lang.text.StrBuilder$StrBuilderWriter.class org.apache.commons.lang.text.StrBuilder.class org.apache.commons.lang.text.StrLookup$MapStrLookup.class org.apache.commons.lang.text.StrLookup.class org.apache.commons.lang.text.StrMatcher$CharMatcher.class org.apache.commons.lang.text.StrMatcher$CharSetMatcher.class org.apache.commons.lang.text.StrMatcher$NoMatcher.class org.apache.commons.lang.text.StrMatcher$StringMatcher.class org.apache.commons.lang.text.StrMatcher$TrimMatcher.class org.apache.commons.lang.text.StrMatcher.class org.apache.commons.lang.text.StrSubstitutor.class org.apache.commons.lang.text.StrTokenizer.class org.apache.commons.lang.time.DateFormatUtils.class org.apache.commons.lang.time.DateUtils$DateIterator.class org.apache.commons.lang.time.DateUtils.class org.apache.commons.lang.time.DurationFormatUtils$Token.class org.apache.commons.lang.time.DurationFormatUtils.class org.apache.commons.lang.time.FastDateFormat$CharacterLiteral.class org.apache.commons.lang.time.FastDateFormat$NumberRule.class org.apache.commons.lang.time.FastDateFormat$PaddedNumberField.class org.apache.commons.lang.time.FastDateFormat$Pair.class org.apache.commons.lang.time.FastDateFormat$Rule.class org.apache.commons.lang.time.FastDateFormat$StringLiteral.class org.apache.commons.lang.time.FastDateFormat$TextField.class org.apache.commons.lang.time.FastDateFormat$TimeZoneDisplayKey.class org.apache.commons.lang.time.FastDateFormat$TimeZoneNameRule.class org.apache.commons.lang.time.FastDateFormat$TimeZoneNumberRule.class org.apache.commons.lang.time.FastDateFormat$TwelveHourField.class org.apache.commons.lang.time.FastDateFormat$TwentyFourHourField.class org.apache.commons.lang.time.FastDateFormat$TwoDigitMonthField.class org.apache.commons.lang.time.FastDateFormat$TwoDigitNumberField.class org.apache.commons.lang.time.FastDateFormat$TwoDigitYearField.class org.apache.commons.lang.time.FastDateFormat$UnpaddedMonthField.class org.apache.commons.lang.time.FastDateFormat$UnpaddedNumberField.class org.apache.commons.lang.time.FastDateFormat.class org.apache.commons.lang.time.StopWatch.class
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

老攀呀

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值