数据结构与算法分析(1)

1. 最大子序列和的问题
输入样例:4 -3 5 -2 -1 2 6 -2
输出:11
1.1 使用二分法递归求解代码如下(时间复杂度:O(NlogN)):GCC编译C++使用g++命令

int getMax3 (int a, int b, int c)
{
    int max = a;
    if (max < b)
        max = b;
    if (max < c)
        max = c;
    return max;
}
int getMaxSum(const vector<int> &arr, int bgn, int end)
{
    if (bgn >= end)
        return 0;
    int mid = (bgn + end) / 2;
    int leftMaxSum = getMaxSum(arr, bgn, mid);

    //此处的起始位置应设置为mid + 1,否则会造成无限递归
    int rightMaxSum = getMaxSum(arr, mid + 1, end);

    int leftMaxBorder = 0, leftTmp = 0;
    for (int i = mid; i >= bgn; --i)
    {
        leftTmp += arr[i];
        if (leftTmp > leftMaxBorder)
            leftMaxBorder = leftTmp;
    //    if (leftTmp < 0)    //这个地方不能提前退出,必须完全遍历
    //        break;
    }
    int rightMaxBorder = 0, rightTmp = 0;
    for (int i = mid + 1; i < end; ++i)
    {
        rightTmp += arr[i];
        if (rightTmp > rightMaxBorder)
            rightMaxBorder = rightTmp;
    //    if (rightTmp < 0)
    //        break;
    }
    return getMax3(leftMaxSum, rightMaxSum, leftMaxBorder + rightMaxBorder);
}

1.2 一次性遍历的求解方法如下(时间复杂度O(N)):

int getMaxSubSum(const vector<int> &arr, int bgn, int end)
{
    int maxSum = 0;
    int sumTmp = 0;
    for (int i = bgn; i < end; ++i)
    {
        sumTmp += arr[i];
        if (sumTmp > maxSum)
            maxSum = sumTmp;
        else if (sum < 0)
            sumTmp = 0;
    }
    return maxSum;
}

2. 算法时间复杂度为O(logN)的典型问题:
2.1 对分查找(binary search):时间复杂度(<= log2N)

int binSearch(const vector<int> &arr, int bgn, int end, int target)  //end-尾元素后一位置
{
    int ret = -1;
    while (bgn < end)
    {
        int mid = (bgn + end) / 2;
        if (target == arr[mid])
        {
            ret = mid;
            break;
        }
        else if (target > arr[mid])
            bgn = mid + 1;
        else
            end = mid;
    }
    return ret;
}

2.2 两个整数最大公约数求解(欧几里德算法):时间复杂度(<= 2logN)

unsigned int getGCD(unsigned int m, unsigned int n)
{
    while (n > 0)
    {
        int rem = m % n;
        m = n;
        n = rem;
    }
    return m;
}

  这里其实运用了递归的思想:m与n的最大公因子即是n与rem(m%n)的最大公因子...,那么,只需要说明n与rem的最大公因子就是m与n的最大公因子即可使这个递归进行下去。所以问题是n与rem的最大公因子为什么就是m与n的最大公因子?

思路:假设m > n,又即使m < n,经过一次遍历后有m > n,m与n的最大公因子是A,则m = xA, n = yA。
  rem = m%n -> m-zn(z = m/n),当rem=0,n即是两者的最大公因子;rem>0,rem=xA - zyA,很显然rem%A = 0
         -> m与n的最大公因子即是n与rem的最大公因子,以此类推

2.3 幂运算:时间复杂度(<= 2logN)

long long pow(long long x, unsigned int n)
{
    if (0 == n)
        return 1;
    if (n % 2)
        return pow( x*x, n/2 ) * x;
    else
        return pow( x*x, n/2 );
}

  以2^15为输入,则恰需要 2log(15) = 6 次乘法运算
  以2^16为输入,则仅需要 4+1(<2log(16)=8) 次乘法运算,也可以修改下代码添加出口判断(if (1 == n))使之成为4次乘法运算,不过需要每次进入pow多判断一次

  PS: 1. 书上以2^62为例,共需9次乘法运算,但所推演算法过程个人觉得有问题。实际过程应该是首先层层运算pow入口参数x*x的值,直至n == 0。
     然后,再逆序层层计算pow*x的值,直至算法结束运算
    2. 代码中语句pow( x*x, n/2 )可以用pow( x, n/2 )*pow( x, n/2 )代替,但是效率会非常低,因其进行了大量的重复性工作

时间: 2025-01-02 13:32:30

数据结构与算法分析(1)的相关文章

数据结构1:数据结构和算法分析

问题引出 假设有一道题目:有一组N个数而要确定其中第k个最大者,我们称之为选择问题,那么这个程序如何编写?最直观地,至少有两种思路: 1.将N个数读入一个数组中,再通过某种简单的算法,比如冒泡排序法,以递减顺序将数组排序,则第k个位置上的元素就是我们需要的元素 2.稍微好一些的做法,将k个元素读入数组并以递减顺序排序,接着将接下来的元素再逐个读入,当新元素被读到时,如果它小于数组中的第k个元素则忽略之,否则将其放到数组中正确的位置上,同时将数组中的一个元素挤出数组,当算法终止时,位于第k个位置上

《数据结构与算法分析》学习笔记(二)——算法分析

一.对算法分析方法的最简单的理解和使用方法 1.首先大家可能一般会被那些数学的概念搞晕,其实简单理解下来,就是假设任何语句执行的效率都是一样的,所以设定每一个语句的执行时间都是一个时间单位,那么只要计算这个程序到底执行了多少语句,就可以算出其时间复杂度. 2.其次就是我们要明白,我们是个估算,所以可以进行化简,明显我们可以忽略那些相对来说低阶的项,只分洗最高阶项.然后主要就是有这些常见的法则: (1)FOR循环 一次for循环的运行时间至多是该for循环内语句的运行时间乘以迭代次数. (2)嵌套

《数据结构与算法分析:C语言描述》复习——第十章“算法设计技巧”——Alpha-Beta剪枝

2014.07.08 22:43 简介: “搜索”与“剪枝”几乎是如影随形的.此处的“搜索”指的是带有回溯算法的深度优先搜索. 在之前的“Minimax策略”中我们给出了一个三连棋的程序,运行后你就知道计算一步棋要花多少时间. 为了计算最优的一步棋,我们可能需要递归9万多次.如果毫无疑问这种阶乘式的穷举过程必须通过剪枝来加速. 本篇介绍一种用于Minimax策略的剪枝思路——α-β剪枝. 剪枝的英语是pruning,所以不要想当然说成trimming. 图示: 在上一篇讲解Minimax策略的博

《数据结构与算法分析:C语言描述》复习——第四章“树”——AVL树

2014.06.15 16:22 简介: AVL树是一种高度平衡的二叉搜索树,其命名源自于联合发明算法的三位科学家的名字的首字母.此处“平衡”的定义是:任意节点的左右子树的高度相差不超过1.有了这个平衡的性质,使得AVL树的高度H总是接近log(N),因此各种增删改查的操作的复杂度能够保证在对数级别.没有bad case是AVL树与普通的二叉搜索树的最大区别.为了实现平衡性质,我们需要记录每个节点的高度(或者平衡因子)来检测不平衡的情况.为了修正高度不平衡,需要用到“旋转”的方法,分为单旋转和双

《数据结构与算法分析—C语言描述》pdf

下载地址:网盘下载 内容简介 编辑 <数据结构与算法分析:C语言描述(原书第2版)>内容简介:书中详细介绍了当前流行的论题和新的变化,讨论了算法设计技巧,并在研究算法的性能.效率以及对运行时间分析的基础上考查了一些高级数据结构,从历史的角度和近年的进展对数据结构的活跃领域进行了简要的概括.由于<数据结构与算法分析:C语言描述(原书第2版)>选材新颖,方法实用,题例丰富,取舍得当.<数据结构与算法分析:C语言描述(原书第2版)>的目的是培养学生良好的程序设计技巧和熟练的算

《数据结构与算法分析》引论:选择问题实现

在<数据结构与算法分析--C语言描述>的引论中有提到一个问题: 设有一组N个数而要确定其中第k个最大者. 被称为选择问题(selection problem). 后面有提到两种算法,下面是我根据描述,写的代码: /* * 来源:<数据结构与算法分析>引论 * 题目:选择性问题,从N个数中找出第k大者 * * */ #include <stdio.h> #include <stdlib.h> /* * 输出数组 * */ void printfArray(in

《数据结构与算法分析:C语言描述》复习——第六章“排序”——冒泡排序

2014.06.17 01:04 简介: 冒泡排序是O(n^2)级别的交换排序算法,原理简单,属于必知必会的基础算法之一. 思路: 排序要进行N轮,每一轮从尾部逐个向前扫描,遇到逆序对就进行交换.确保每一轮把最小的元素交换到前面去.这个过程好比水中的气泡向上飘,所以叫冒泡排序.代码非常简单,所以语言描述反而显得麻烦了. 实现: 1 // My implementation for bubble sort. 2 #include <iostream> 3 #include <vector&

[数据结构与算法分析(Mark Allen Weiss)]二叉树的插入与删除 @ Python

二叉树的插入与删除,来自Mark Allen Weiss的<数据结构与算法分析>. # Definition for a binary tree node class TreeNode: def __init__(self, x): self.val = x self.left = None self.right = None class BinarySearchTree: # @param root, a tree node # @return a list of integers def

数据结构与算法分析-索引

作者:xiabodan 出处:http://blog.csdn.net/xiabodan 算法和数据结构是计算机科学的核心内容.作为程序猿,编程是我们的实战项目.然而,写出程序还不够.一个程序在应对一些大型而复杂的情况时.会耗费大量的时间.我们能够非常easy写出一个从文件里找到一个词的程序.比方逐词扫描.看是否相符.但假设我们的文件有几十TB,并且要从文件里找到上百个词,逐个扫描的办法就差点儿不可行.我们须要优化程序,以便我们的程序能够应对复杂问题. 算法研究解决这个问题的方法,而数据结构则是

数据结构和算法分析

转自[五月的仓颉] http://www.cnblogs.com/xrq730/p/5122436.html 数据结构 数据结构是计算机存储.组织数据的方式,是指数据相互之间存在一种或多种特定关系的数据元素的集合.通常情况下,精心选择的数据结构可以带来更高的运行或者存储效率(这就是为什么我们要研究数据结构的原因),数据结构往往同高效的检索算法和索引技术相关. 常见的数据结构有数组.栈.队列.链表.树.散列等,这些数据结构将是本数据结构的分类中重点研究的对象. 算法分析 算法是为求解一个问题需要遵