概述/唠嗑:
本周学习的重点还是算法,还有一些Java基础知识和课题研究:
1)按照leetcode中剑指Offer的顺序刷题(还偶尔刷了些类似的题目),总共过了22道题,刷题过程中也看了Carl哥的代码随想录,但看的还比较少,只看到了二分查找部分,不得不说Carl哥确实强,用一个区间的定义解决了二分查找的很多细节问题,对我的刷题很有帮助。
2)刷题过程中,也发现了很多Java中我不熟悉的用法(虽然之前用过,但都忘了),比如栈Stack、队列LinkedList(还是双端队列);又比如HashMap、HashSet等类包含的各种方法,并且有的还看了底层源码以及实现原理(但由于时间原因,看得并不深入),在后面我会做一些个人总结,然后附上来源地址(可以去链接中详细看)。
3)由于周四晚上要开组会,所以周三临时抱了抱佛脚,看了一篇浙大团队关于语义通信的文章,然后用实验室的服务器跑了这篇论文的开源代码。
刷题列表:
- 剑指 Offer 09. 用两个栈实现队列
- 剑指 Offer 30 包含min函数的栈
- 1. 两数之和
- 2. 两数相加
- 剑指 Offer 24 反转链表
- 剑指 Offer 06. 从尾到头打印链表
- 剑指 Offer 05. 替换空格
- 剑指 Offer 03 数组中重复的数字
- 剑指 Offer 53 - I. 在排序数组中查找数字 I
- 剑指 Offer 53 - II. 0~n-1中缺失的数字
- 704. 二分查找
- 剑指 Offer 35. 复杂链表的复制
- 剑指 Offer 58 - II. 左旋转字符串
- 剑指 Offer 11. 旋转数组的最小数字
- 剑指 Offer 50. 第一个只出现一次的字符
- 剑指 Offer 04. 二维数组中的查找
- 剑指 Offer 32 - I. 从上到下打印二叉树
- 剑指 Offer 32 - II. 从上到下打印二叉树 II
- 剑指 Offer 32 - III. 从上到下打印二叉树 III
- 剑指 Offer 27. 二叉树的镜像
- 剑指 Offer 10- II. 青蛙跳台阶问题
- 剑指 Offer 10- I. 斐波那契数列
Java基础知识 :
- Java八种基本数据类型:byte, short, int, long, float, double, boolean, char(其中char的包装类为Character,其他都是首字母大写)(from: Java 基本数据类型 | 菜鸟教程)
- int和Integer有区别:int是基本数据类型;而Integer是封装类,继承的Object类,必须实例化后使用,Integer i = new Integer(100);Integer实际上是对象的引用,当new一个Integer时,实际上是生成一个指针指向此对象,而int则是直接存储数据值;Integer默认是null,int默认值是0。(from: int和Integer的区别)
- 泛型不能是基本数据类型,只能是对象类型(即不能是int,而应该是Integer)
Integer的equals()函数在封装时已经重写过,是基于内容比较,而不是引用地址(基本类型比较时用==,对象比较时用equals)关于equals()的文章:Java中的equals()方法 - Map是一个接口类,HashMap继承了AbstractMap,AbstractMap实现了Map。
HashMap不支持线程的同步,是非线程安全的,即任一时刻可以有多个线程同时写HashMap,可能会导致数据的不一致。如果需要同步,可以用 Collections和synchronizedMap方法使HashMap具有同步能力,或者使用ConcurrentHashMap。
HashMap只允许一个key为null的数据 可以(null,"123")。 - HashMap用法:Java HashMap | 菜鸟教程
.put(key, value)(多次put同一个key时,value为最后一个put的值,即会覆盖;put(null, 1));
.get(key)(可以get(null),key只能有一个null,没定义(null, value)时返回null);
.getOrDefault(key, default); .remove(key); .clear(); .size(); .isEmpty(); containsKey(key); .containsValue(value); .replace(key, newValue); .entrySet(); .keySet(); .values(); - HashSet用法:Java HashSet | 菜鸟教程
.put(); .remove(); .contains(); .isEmpty(); .clear(); .size(); - Java规定,不初始化就无法引用,其中赋值为null也算初始化
(from: 局部变量声明而不赋值,和赋值为null,在内存分配上有什么区别?)
赋值为null也相当于初始化了,而Java要求不初始化是根本无法引用的,所以
ListNode pre; current.next = pre; 第二句话会报错(加上pre = null;就不会报错了) - 基本数据类型不能赋值为null: int a = null;(×);Integer a = null;(√);成员变量在类对象声明时会自动赋初始值;全局变量不需要赋初始值;局部变量不会自动初始化,必须手动初始化。java中对象引用放在栈中,对象的实例放于堆中,如果为null,说明只在栈中(没有指向堆中的实例化对象)。
(from:Java中声明一个对象并赋值NULL或者只声明不赋值) - StringBuilder和StringBuffer:与String不同的是,两类的对象都能被多次修改,且不会产生新的对象,StringBuffer是线程安全的;而StringBuilder不是,但他的速度更快,多数情况下建议使用StringBuilder。(参考:Java StringBuffer 和 StringBuilder 类 | 菜鸟教程)
- 数组、字符串、集合的长度:
数组是一个容器,被创建后,它的数据类型和长度都已经是确定的了,所以只需使用length字段存储。
而String是一个类,其中 char[] value是private的,无法直接获取value的length,所以提供了length()函数返回string长度。
Collection用size()方法来计算集合的长度。
(参考:java获取数组长度length、字符串长度length()、集合大小size()) - 【排序数组】中搜索问题,首先想到【二分法】。
- JAVA中右移一位和除以2的区别:
非负数时:两者结果相同,除以2是向0取整,右移一位是向下取整:
eg: -5/2 = -2; -5>>1=-3; (参考:JAVA中右移一位和除以2的区别) - 报错:required: variable found: value
左值右值问题:左值是值和地址都能确定的操作数(变量),右值只要知道值即可。
hashmap.get(key)得到的是值而不是地址。
所以修改hashmap的值的时候可以使用hashmap.replace(key, newValue); 或者hashmap.put(key, newValue); (参考:required variable found value) - Queue是java中实现队列的接口,它总共只有6个方法(add, offer, remove, poll, element, peek),我们一般只用其中3个(offer, poll, peek,有异常处理)就可以了。Queue的实现类有LinkedList和PriorityQueue。
LinkedList:Java LinkedList | 菜鸟教程 (双端队列,两头都可以入队或出队)
linkList.get(i)时间复杂度是O(n),因为是基于链表实现的。
(参考:[集合]LinkedList源码和时间复杂度) - Java栈的实现类Stack:(参考:Java Stack 类 | 菜鸟教程)
.pop(); .push(); .peek(); - Collections.reverse(tmp); 将集合tmp中的元素反转
- ArrayList:(参考:一文了解Java ArrayList (源码逐行解析)(全网最细))
基于动态数组实现,所以arrayList.get(i); 时间复杂度为O(1)
add(); size(); remove(); contains(); isEmpty(); - debug时可以在纸上画画,在脑子里想容易想乱。
下周计划
上周开组会时被老师说进度太慢,因为最近都在看数据结构和算法,确实没怎么研究课题相关的内容,所以这周需要多花点精力放在语义通信的论文和代码上,然后想想开题报告应该怎么写,可以大致先出一版。
感觉上一周的刷题有些没有体系,虽然是跟着剑指Offer刷的,但是感觉不系统,不利于对算法各模块的整体理解,所以这周打算跟着代码随想录刷题,看书和刷题相结合。下周见!