算法和数据结构1.1数据结构的定义
数据结构决定了数据的顺序和位置关系
数据存储在计算机的内存中的时候,决定了数据顺序和位置关系的是“数据结构”
电话本的数据结构:
1.从上往下顺序添加:
举例来说:假设有个电话本,虽然说现在很多人吧电话存在手机里面,但是这里考虑到写在纸上的情况,每当我们得到了新的电话号码,就按照从上往下的顺序把他们记录在电话本上面。
假设我们想给其中的一个人打电话,但是因为数据都是按照获取顺序排列的,所以,在找这个具体号码时候,我们只能从头一个个往下找。如果电话本上的号码不多的话很快就能找到,但是如果存了很多号码,找起来就没那么容易了。
2.按照姓名的拼音顺序排列
如果按照联系人的姓名拼音顺序排列,那么数据都是有结构的,类似于字典类型。
使用这种方法存储,想要找到目标任务就轻松多了。通过姓名的拼音首字母就能推测出该数据大致位置。
而这种情况下,如果想要存储一个号码,如果需要插入一个号码到两个号码之间,那么就需要把后面的号码都执行“将本行内容写进下一行”,如果数据很多,那么就非常耗费时间
两种方法的优缺点:
总的来说:如果数据按照顺序排列,虽然添加数据很简单,但是查找数据很麻烦。
如果按照拼音顺序排列,虽然查询简单,但是添加数据比较麻烦
将号码获取顺序和拼音顺序结合起来使用:
先创建所有首字母的表从A-Z,然后在每个表中存储数据时候按照号码获取到的顺序来存储
这样做的结果是:添加新数据时候,找到对应的首字母,直接将数据添加到对应首字母的表的末尾,查询数据时候,也只需要到对应的表中查找即可
因为各个表中存储的数据依旧是没有规律的,所以查询时仍需从表头开始找起,但是比起来查询整个电话本来说要轻松
选择合适的数据结构以提高内存的利用率
数据结构的思路和电话本存储一样。将数据存入内存时候,根据使用目的的选择合适的数据结构,可以提高内存的利用率。
数据结构是呈线性排列的,但是我们可以使用指针等道具,构造出“数形”的复杂结构。
leetcode上有这么一道题求解两数之和。
给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。
你可以假设每种输入只会对应一个答案。但是,数组中同一个元素不能使用两遍。
示例:
给定 nums = [2, 7, 11, 15], target = 9
因为 nums[0] + nums[1] = 2 + 7 = 9
所以返回 [0, 1]
根据题目来看,最快想到的解决方案就是暴力解法,嵌套两个for循环问题就解决了
for(int i = 0;i < nums.count - 1; i ++){
for(int j = i +1;j < nums.count; j ++){
sum = nums[i] + nums[j];
if(sum == target){
return [i,j];
}
}
}
这样解决是可以正常满足题意的,但是算起来假设数组nums长度是n,那么解题所需要的时间复杂度约等于O(n^2).占用的复杂度约等于1.
leetcode上给出了一种使用哈希表的的思路。使用一层for循环来处理问题。
Map<Integer, Integer> hashtable = new HashMap<Integer, Integer>();
for (int i = 0; i < nums.length; ++i) {
if (hashtable.containsKey(target - nums[i])) {
return new int[]{hashtable.get(target - nums[i]), i};
}
//用nums下标i取出来的值nums[i]作为key,将当前下标i做为value存入hashtable中,hashtable.put(key,value)等待下一个for循环中使用。
hashtable.put(nums[i], i);
}
这样做的时间复杂度为O(n),空间复杂度也是O(n).