一、基础知识点的积累
1、 Map.containsKey方法:判断Map集合对象中是否包含指定的键名
containsKey(Object key)map是一个key和value的键值对的集合。有key和value键值对,就会有判断是否有key
2、 deque容器为一个给定类型的元素进行线性处理,像向量一样,它能够快速地随机访问任一个元素,并且能够高效地插入和删除容器的尾部元素。但它又与vector不同,deque支持高效插入和删除容器的头部元素,因此也叫做双端队列。
3、 LinkedList类是双向列表,列表中的每个节点都包含了对前一个和后一个元素的引用.
LinkedList的构造函数如下
- public LinkedList(): ——生成空的链表
- public LinkedList(Collection col): 复制构造函数
4、
stack1.peek() 返回栈顶元素,但不在堆栈中删除它。
Stack2.pop() 返回栈顶元素,并在进程中删除它。
5、 在描述算法复杂度时,经常用到o(1), o(n), o(logn), o(nlogn)来表示对应算法的时间复杂度, 这里进行归纳一下它们代表的含义:
这是算法的时空复杂度的表示。不仅仅用于表示时间复杂度,也用于表示空间复杂度。
O后面的括号中有一个函数,指明某个算法的耗时/耗空间与数据增长量之间的关系。其中的n代表输入数据的量。 比如时间复杂度为O(n),就代表数据量增大几倍,耗时也增大几倍。比如常见的遍历算法。 再比如时间复杂度O(n^2) 就代表数据量增大n倍时,耗时增大n的平方倍,这是比线性更高的时间复杂度。比如冒泡排序,就是典型的O(n^2)的算法,对n个数排序,需要扫描n×n次。
再比如O(logn),当数据增大n倍时,耗时增大logn倍(这里的log是以2为底的,比如,当数据增大256倍时,耗时只增大8倍,是比线性还要低的时间复杂度)。二分查找就是O(logn)的算法,每找一次排除一半的可能,256个数据中查找只要找8次就可以找到目标。
O(nlogn)同理,就是n乘以logn,当数据增大256倍时,耗时增大256*8=2048倍。这个复杂度高于线性低于平方。归并排序就是O(nlogn)的时间复杂度。
O(1)就是最低的时空复杂度了,也就是耗时/耗空间与输入数据大小无关,无论输入数据增大多少倍,耗时/耗空间都不变。 哈希算法就是典型的O(1)时间复杂度,无论数据规模多大,都可以在一次计算后找到目标(不考虑冲突的话)
6、 白名单过滤
如果可能,我们的测试用例都会通过模拟实际情况来展示当前算法的必要性
7、 mid=(left+right)>>1的含义
右移运算符>>,运算结果正好能对应一个整数的二分之一值,这就正好能代替数学上的除2运算,但是比除2运算要快。
mid=(left+right)>>1相当于mid=(left+right)/2
8、 二分查找法
①数组必须是有序的
②被查找的键要么不存在,要么必然存在于a[lo…hi]之中
9、 arraycopy()的使用
public static native void arraycopy(Object src, int srcPos, Object dest, int destPos,int length);
src:要复制的数组(源数组)
srcPos:复制源数组的起始位置
dest:目标数组
destPos:目标数组的下标位置
length:要复制的长度
nums1 = [1,2,3,0,0,0], m = 3
nums2 = [2,5,6], n = 3
System.arraycopy(nums2, 0, nums1, m, n);
输出的结果:[1,2,3,2,5,6]
递归
含义:函数在运行时调用自己,这个函数就叫递归函数,调用的过程叫递归
比如斐波那契数列:F(0)=0,F(1)=1, F(n)=F(n - 1)+F(n - 2)(n ≥ 2,n ∈ N*)
如果代入F(2)→返回F(1)+F(0)…[如果没有后面(n ≥ 2,n ∈ N*)的限制条件的话,就会一直的无限循环下去]
所以从中可以得到两个规律:
1、递归函数必须要有终止条件,否则会出错;
2、递归函数先不断调用自身,直到遇到终止条件后进行回溯,最终返回答案
列题:
将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。
输入:1->2->4, 1->3->4
输出:1->1->2->3->4->4
终止条件:当两个链表都为空时,表示对链表已经合并完成了
递归的形式:判断L1和L2头结点哪个更小,然后较小结点的next指针指向其余结点的next指针指向其余结点的合并递归。(调用递归)
public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
if(l1==null){
return l2;
}else if(l2 ==null){
return l1;
}else if(l1.val<l2.val){
l1.next = mergeTwoLists(l1.next, l2);
return l1;
}else {
l2.next = mergeTwoLists(l1, l2.next);
return l2;
}
}
动态规划
动态规划和递归恰恰是相反的,前者是自底向上求解,后者是自上向下求解。