|
1 | 1 | ### 数组
|
2 | 2 | - 什么是数组
|
3 | | -我们知道常用的数据存储方式有两种:顺序存储和非顺序存储。顺序存储就是把数据存储在一块连续的空间内。数组(array)就是典型的顺序存储,而链表就是典型的非顺序存储。 |
| 3 | +  我们知道常用的数据存储方式有两种:顺序存储和非顺序存储。顺序存储就是把数据存储在一块连续的空间内。数组(array)就是典型的顺序存储,而链表就是典型的非顺序存储。 |
4 | 4 |
|
5 | | -数组通常用于存储一系列相同类型的数据。当我们在创建数组时,会在内存中划分出一块连续的内存用于存储数据,插入数据时,会将数据按顺序存储在这块连续的内存中,读取时通过访问数组的索引迅速取出。数组名就是一个指针,指向这段内存的起始地址。通过数组的类型,编译器知道在访问下一个元素的时候需要在内存中后移多少个字节。由于数组在存储时是顺序存储的,存储数据的内存也是连续的,所以数组在读取数据时比较容易,随机访问速度快,但是插入和删除就比较费劲了。读取可以直接根据索引,插入和删除则比较耗时,插一个数据需要移动大量元素,在内存中空出一个元素的空间,然后将要增加的元素放在其中,如果想删除一个元素,同样需要移动大量元素去掉被移动的元素。所以如果需求是快速访问数据,很少或者几乎不插入和删除元素,数组是一个不错的选择。 |
| 5 | +  数组通常用于存储一系列相同类型的数据。当我们在创建数组时,会在内存中划分出一块连续的内存用于存储数据,插入数据时,会将数据按顺序存储在这块连续的内存中,读取时通过访问数组的索引迅速取出。数组名就是一个指针,指向这段内存的起始地址。通过数组的类型,编译器知道在访问下一个元素的时候需要在内存中后移多少个字节。由于数组在存储时是顺序存储的,存储数据的内存也是连续的,所以数组在读取数据时比较容易,随机访问速度快,但是插入和删除就比较费劲了。读取可以直接根据索引,插入和删除则比较耗时,插一个数据需要移动大量元素,在内存中空出一个元素的空间,然后将要增加的元素放在其中,如果想删除一个元素,同样需要移动大量元素去掉被移动的元素。所以如果需求是快速访问数据,很少或者几乎不插入和删除元素,数组是一个不错的选择。 |
| 6 | + |
| 7 | +  最常见的有一维数组和二维数组,稍微复杂一点的是多维数组和动态数组。在c++中,STL提供了Vector,在Java中,Collection集合中提供了ArrayList和Vector,对于Python而言,内置的List就是一个动态指针数组。当列表中没有空间存储新的元素时,列表会动态地改变大小以容纳新的元素,每次改变大小时,会预留一部分空间以降低改变大小的频率。 |
6 | 8 |
|
7 | | -最常见的有一维数组和二维数组,稍微复杂一点的是多维数组和动态数组。在c++中,STL提供了Vector,在Java中,Collection集合中提供了ArrayList和Vector,对于Python而言,内置的List就是一个动态指针数组。当列表中没有空间存储新的元素时,列表会动态地改变大小以容纳新的元素,每次改变大小时,会预留一部分空间以降低改变大小的频率。 |
8 | 9 | - 类别
|
9 | | -1.无序数组 |
| 10 | +1.无序数组 |
10 | 11 | - 概念:未经过排序的数组
|
11 | 12 | - 优点:插入快
|
12 | 13 | - 缺点:查找慢,删除慢,大小固定
|
|
25 | 26 | - 根绝数据量判断:数据量小且可预知,查询速度比插入速度更重要使用有序数组;数据量大且不可知,插入速度比查询速度更重要使用无序数组。
|
26 | 27 |
|
27 | 28 | ### 题型总结
|
| 29 | +【一维数组】 |
28 | 30 | #### 1.K-Sum
|
29 | | -这类题目通常会给定一个数组和一个值,让求出这个数组中两个/三个/K个值的和等于这个给定的值target。leetcode第一题就是two-sum,对于这类题目,首先看题目要求的时间复杂度和空间复杂度是什么,其次看有没有限制条件,如要求不能有重复的子数组或者要求按照升序/降序排列等。解法如下: |
| 31 | +  这类题目通常会给定一个数组和一个值,让求出这个数组中两个/三个/K个值的和等于这个给定的值target。leetcode第一题就是two-sum,对于这类题目,首先看题目要求的时间复杂度和空间复杂度是什么,其次看有没有限制条件,如要求不能有重复的子数组或者要求按照升序/降序排列等。解法如下: |
30 | 32 | - 暴力解法:最常见,但是通常会超时,只能作为备选,
|
31 | 33 | - hash-map:建立一个hash-map循环遍历一次即可
|
32 | 34 | - two-pointers:定位两个指针根绝和的大小来移动另外一个。这里设定的指针个数根据题目中K的个数来定。3Sum中可以设定3个指针,固定两个,移动另一个
|
33 | 35 |
|
34 | 36 |
|
35 | 37 | #### 2.区间问题
|
36 | | -这类题目通常会给一个包含多个子数组的数组,然后针对区间是否重合来判断true or false。解题技巧: |
| 38 | +  这类题目通常会给一个包含多个子数组的数组,然后针对区间是否重合来判断true or false。解题技巧: |
37 | 39 | 1. 按start排序
|
38 | 40 | 2. 在前一个区间的end和后一个区间的start找交集
|
39 | 41 | - 例题:252 meeting room[easy](https://leetcode.com/problems/meeting-rooms/)
|
|
42 | 44 | >Example1:
|
43 | 45 | >Input: [[0,30],[5,10],[15,20]]
|
44 | 46 | >Output: false
|
45 | | ->Example2: |
46 | | ->Input: [[7,10],[2,4]] |
| 47 | +>Example2: |
| 48 | +>Input: [[7,10],[2,4]] |
47 | 49 | >Output: true
|
48 | 50 |
|
49 | 51 | - 解题思路:在这个题目里,如果一个人要参加所有会议,那么所有会议的时间应该不能重合,所以只需要判断后一个会议开始的start > 前一个会议结束的end就就可以,如果end>start,就返回false。首先得先对所有子数组的start进行排序,然后再进行判断start和end
|
@@ -78,15 +80,15 @@ class Solution(object):
|
78 | 80 | ```
|
79 | 81 |
|
80 | 82 | #### 子数组类题目
|
81 | | -这类题目通常会在一个包含多个子数组的数组中,求和/积,最大最小等。形式有很多种,例如求一个数组中和最小的子数组(209题),或者积最小的子数组(238题) |
| 83 | +  这类题目通常会在一个包含多个子数组的数组中,求和/积,最大最小等。形式有很多种,例如求一个数组中和最小的子数组(209题),或者积最小的子数组(238题) |
82 | 84 | - 解题技巧:
|
83 | 85 | - 滑动窗口(sliding window)
|
84 | 86 | - 例题:209 Minimum Size Subarray Sum[Medium]
|
85 | 87 | - 题目理解:给定我们一个数字,让我们求子数组之和大于等于给定值的最小长度
|
86 | 88 | - test case:
|
87 | | -Input: s = 7, nums = [2,3,1,2,4,3] |
88 | | -Output: 2 |
89 | | -Explanation: the subarray [4,3] has the minimal length under the problem constraint. |
| 89 | +>Input: s = 7, nums = [2,3,1,2,4,3] |
| 90 | +>Output: 2 |
| 91 | +>解释:满足子数组和=7的最小长度数组是[4,3],所以output=2 |
90 | 92 | - 解题思路:求的数字要大于等于这个数字target,譬如这个testcase中,[2,3,1,2,4,3],从前往后相加,前四项相加的和为8.已经大于7了,但是我们的target是7,后面的几项也都是正整数,继续往后走,肯定也会大于target7,所以这个时候我们把left指针往右移动一位,那么就是相当于成为了一个滑动窗口(sliding window),这种方法在String类型的题目出现的更多。
|
91 | 93 | 
|
92 | 94 | - code:
|
@@ -121,4 +123,8 @@ def minSubArrayLen(self, s, nums):
|
121 | 123 | return result if result <= len(nums) else 0
|
122 | 124 | ```
|
123 | 125 |
|
| 126 | +【二维数组】 |
| 127 | +#### 4.Rotate题型 |
| 128 | + |
| 129 | + |
124 | 130 |
|
0 commit comments