目录
1.map常用方法:
Vget(object key):如果没有返回null
对于HashMap来说元素的插入顺序和元素的存储顺序是不一定的,若想俩个顺序一直就需要换个子类,用LinkedHashMap这个子类。
key值可以为空,但是同时有俩个null的时候只保留一个,然后进行更新操作。
value值也可以为null, value值可以重复,所以都会保留。
TreeMap不可以null,会有空指针异常
总结:
2.笔试题力扣138:链表复制
原链表和新链表除了地址不一样之外,其他都一样
这是Node类
思路:
1.先不管random,先做数组的深拷贝,即遍历原链表,每当走到一个节点就创建一个新节点,值与原链表相同。
创建一个虚拟头节点,从尾插法就可连接到新链表的next域。
2.新1.next=原1.next的映射
把原链表中的next和random都从原链表中一一映射过来
代码如下:
public class Num138 { private class Node{ int val; Node next; //随机指针,可以指向链表中任意一个节点 Node random; public Node (int val){ this.val=val; this.next=null; this.random=null; } } public Node copyRandomList(Node head){ //边界 if(head==null){ return null; } //遍历原链表节点,,构造新链表节点,存储在Map中 //Map<原链表节点,新链表节点> //原1=>新1 Map<Node,Node> nodeMap =new HashMap<>(); //进行遍历 for (Node x =head;x!=null;x=x.next){ //构建新链表的节点 Node node =new Node(x.val); //Map<原链表节点,新链表节点>,这里就把他俩俩放进去了 nodeMap.put(x,node); } //对新链表进行连接操作 //原1.next和新1.next一一对应 //原1.Ramdom和新1.Random一一对应 //对于Map来说Key都是原链表的节点 //原1.next=原3=>新1.next=新3(这个地址就可以根据原3取得) for(Node x=head;x!=null;x=x.next) {//遍历原链表 //对于Map来说 //原1.next=原3 nodeMap.get(x).next=nodeMap.get(x.next);//新1.next=原(1.next)的对应映射 //原1.random=原5 nodeMap.get(x).random=nodeMap.get(x.random); } //返回新链表的头节点,也就是原链表的映射 return nodeMap.get(head); } }
3.笔试题牛客旧键盘打字问题
所谓坏掉的键就是实际中不存在,但是希望存在。
问题:List和Set集合有啥区别
Set集合不可包含重复元素
toLowerCase();
toUpperCase();
代码如下:
public class NewCoderBadKayBoard { public static void main(String[] args) { Scanner scanner =new Scanner(System.in); //期望输入的 String expectedStr=null; //实际输入的 String actualStr=null; while(scanner.hasNext()) { expectedStr=scanner.next();//第一行输入的 actualStr=scanner.next();//第二行输入的 } //输出的是全大写的,将大写的字符串转为大写处理 expectedStr =expectedStr.toUpperCase(); actualStr=actualStr.toUpperCase(); //实际遍历输入的字符串,使用Set集合存储不重复的元素 Set<Character> actualSet=new HashSet<>(); for (int i = 0; i < actualStr.length(); i++) { actualSet.add(actualStr.charAt(i)); } //拿着实际输入的Set集合来遍历期望输入的字符串 //坏键就是期望有实际没有的字符 //再用一个Set集合来去重,去的是实际字符串中重复的元素,也就是坏键有可能出先多次,但是存储一次就够了 Set<Character> set=new HashSet<>(); for (int i = 0; i < expectedStr.length(); i++) { char c=expectedStr.charAt(i); if(!actualSet.contains(c)){//就是期望中有,实际中没有 //去重 if(set.add(c)){ //c确实是期望中有,实际中没有,而且是第一次出现的 System.out.println(c); } } } System.out.println();//换行 } }
4.二分搜索树
上面指的是TreeMap就是基于二分搜索树实现的,这里值不相同是因为TreeMap的key值不能重复。
二分搜索树的特点:BST(BinarySeachTree)
判断二叉树是不是二分搜索树:
对该树进行中序遍历就可以得到一个升序集合,则这个树就是二分搜索树
对二分搜索树查找的过程,实际上就是一个二分查找的过程。
在一个有序区间进行二分查找的时间复杂度为log(n)
4.1向BST中添加一个元素
新添加的元素一定是作为叶子节点。
4.2 key以及value的值是否存在
代码如下
4.3在BST中寻找最小值
对于任意一颗二叉树,最小值一定处在左树的最左侧,但是不一定是叶子节点。
方法:不断地向左树递归查找,找到的第一个左子树为空的节点一定是当前BST的最小值。
node.left=null
node一定是最小值
4.4在BST中寻找最大值
4.5BST中修改一个已经存在的元素
删除最小值和最大值
删除最小值时root.right=root=null的含义 (就是让这个节点与这颗树断开联系,并且让jvm删除这个节点)
root.right =null是为了删除16右子树的那根线
root=null为了让JVM删除16这个节点
任意值删除
如果删除节点有左右孩子
这俩行代码的顺序可以反吗?
不可以。
先执行2就是如下结果,删除的就是42了,因为现在存在子树,最小值为42
4.5BST退化的场景
BST是非常高效的查询数据的结构,但也会有退化的场景。
如果BST只有右子树那就会退化,为了避免这种现象,出现了AVL、二叉平衡搜索树、红黑树。
B+树:多叉二叉平衡搜索树
2-3树、2-3-4树
5.哈希表
而 哈希函数一般不用我们自己设置,JDK中内置的Object类的hashCode方法可以把任意一个数据类型通过hashCode方法转为int。
常见面试题:
在比较对象是否相等时,hashCode和equals有啥关系?
hashCode相同的对象equals一定相同吗?false(不同的key值对应了相同的hash,哈希冲突)
equals方法相同的对象hashCode的值一定相同吗?(必须相同)
6.comparable与Compatar的区别:
第一个是本身这个类实现了接口,具有比较的能力,第二个是本身没有比较的能力,传入new FreqTwoDesc()作为比较器传入。