您的位置:首页 > 理论基础 > 数据结构算法

浅谈数据结构与算法分析学习及如何进行算法分析

2017-01-26 21:54 459 查看

一、前言

都说数据结构与算法分析是程序员的内功,想要理解计算机世界就不能不懂点数据结构与算法,然而这也备受争议,因为大多数的业务需求都用不上数据结构与算法,又或者说已经有封装好的库可以直接调用,例如Java中的ArrayList与LinkedList,直接调用add、remove等方法就已经可以完成插入删除等基本操作,实现业务逻辑,而无需关注其内部实现。如果说一样东西有没有用是根据用不用得上来衡量的话,那么只写业务逻辑确实没什么卵用,但是个人觉得有没有用是根据对自己有没有帮助来判断的,对自己有帮助==这个东西对我有用。

实话说,自己一开始是因为要准备企业面试才打算学习的数据结构与算法(趁着当当网搞活动的时候买了本《数据结构与算法分析Java语言描述》,打算在寒假的时候看),期间也看过不少文章,开复先生就曾经写过一篇文章聊算法的重要性,当时就觉得懂算法的人好厉害。但真正让我开始重视数据结构与算法的是Leetcode的第一道题目TwoSum.

给定一个数组和一个得数,返回数组中两个数字相加等于得数的这两个数字的索引

example

Given nums = [2, 7, 11, 15], target = 9,

Because nums[0] + nums[1] = 2 + 7 = 9,
return [0, 1].


我的解法

public class Solution {
public int[] twoSum(int[] nums, int target) {
int result[] = new int[2];
for(int x = 0;x<nums.length;x++){
for(int y = x+1;y<nums.length;y++){
if((nums[x]+nums[y])==target){
result[0] = x;
result[1] = y;
}
}
}
return result;
}
}


别人的解法

public int[] twoSum(int[] numbers, int target) {
int[] result = new int[2];
Map<Integer, Integer> map = new HashMap<Integer, Integer>();
for (int i = 0; i < numbers.length; i++) {
if (map.containsKey(target - numbers[i])) {
result[1] = i + 1;
result[0] = map.get(target - numbers[i]);
return result;
}
map.put(numbers[i], i + 1);
} return result;
}


虽然都可以运行,但是明显别人的解法比我的优雅的太多太多。我的想法是用两个循环穷举,而别人是用了HashMap来存储数据,并且在循环中同时进行插入和判断,时间复杂度我的是O(n2),而别人的是O(n),如果数据规模大,运行时间则相差巨大。

可见同样的问题,不同人采取的解决方式是可以体现出差别的,这就关系到数据结构与算法

目前对数据结构与算法的理解

数据结构:为了解决问题采用的更有效率的数据组织方式

算法:为了解决问题采用的更加快速的程序设计思想

作为一个想在技术领域打拼十年的菜鸟,有必要学习数据结构与算法。讲真,这还是挺难学的,《数据结构与算法Java语言描述》这本书看了有一半,后面的还看不太懂,前面的又忘了,觉得有必要总结一下。

网络上也有人非常详细的总结了这本书前两章的内容数据结构与算法分析(一):基础算法分析,在这里就不重复造轮子了,只总结一些想加深印象的内容。

二、如何进行算法分析

(一)分析前提

计算模型:假设有无限内存的模型机做任一件简单的工作都恰好花费一个时间单位,并且不存在矩阵求逆或排序之类的想象操作。

(二)分析重点

1.运行时间(时间复杂度)

影响因素:
4000
输入大小n以及所使用的算法

2.占用内存(空间复杂度)

影响因素:算法本身存储占用、输入输出数据占用以及算法运行过程临时占用

(三)时间复杂度计算——大O标记法(运行时间的上界,注意简化常数项与低阶项)

example:计算∑Ni=0i3的运行时间

public static int sum(int n) {
int partialSum;
partialSum = 0;
for(int i = 1; i <= n; i ++)
partialSum += i * i * i;
return partialSum;
}


所有的声明均不计时间

第3行和第6行各占一个时间单元

第5行每执行一次占用4个时间单元(两次乘法、一次加法、一次赋值),执行N次共4N个时间单元

第4行初始化i占用1个时间单元、测试i<=n为N+1个时间单元、i++自增运算为N个时间单元,共2N+2个时间单元

忽略调用方法和返回值的开销,共6N+4个时间单元

故该方法是O(N)的

快速判断法则:

1.for循环

一个for循环的运行时间至多是该for循环内部那些语句(包括测试)的总运行时间乘以迭代的次数

2.嵌套的for循环

从里向外,一组嵌套循环内部的一条语句总的运行时间为该语句的运行时间乘以该组所有的for循环的大小的乘积

3.顺序语句

各语句运行时间求和

4.if/else语句

一个if/else语的运行时间不超过 判断的运行时间+if语句/else语句中较长的运行时间

分析的基本策略是从内部(或最深层的部分)向外展开工作的。有方法调用则首先分析方法调用;有递归过程,则具体情况具体分析

(四)空间复杂度计算

当算法占用空间大小不随数据量n变化而变化,其空间复杂度可记为O(1)

当算法占用空间大小随数据量n变化而线性变化,其空间复杂度可记为O(n)

在程序开发中,我们所指的复杂度不做特别说明的情况下,就是指时间复杂度。现在的硬件发展速度之快使得我们完全可以不用考虑算法所占的内存,通常都是用空间换取时间。加之算法的空间复杂度比较难算,所以我们都侧重于时间复杂度。

三、数据结构与算法分析学习目标

学习,要以解决问题为导向,因此要:

1.了解各种数据结构的结构性质,以便遇到问题可以快速选取合适的数据结构

2.了解各大算法的性能及应用场景,以便遇到问题可以快速选取合适的算法

参考资料及资源站点

《数据结构与算法分析:Java语言描述》

数据结构与算法动态可视化中文站点

数据结构与算法/leetcode/lintcode题解
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  数据结构 算法