剑指Offer-中等知识整理
中等题目中经常有判断数组、ArrayList中是否有重复元素,遇到重复的题目时,个人体感就两种,一种暴力解决,但是肯定不是面试官想问的,另一种就可以考虑哈希。由于之前使用java编程很少用高级数据结构,因此没用过HashMap、HashSet。另,在看顺子那题的时候,看到一个解答使用了TreeSet,在此一并整理。
HashMap
整理的资料:顾名思义,HashMap是Hash和Map的结合,;Map说白了就是键值对(key-value)。HashMap实质上就是将key映射到一个唯一的哈希值上并存储下来。于是在查询或者遍历的时候,我们并不关心我们自己存储数据的先后顺序,只需要根据key的值经过映射,找到对应的哈希值,然后拿到对应的value即可,由于这个步骤只经过一个数学上的映射,也可以理解为一个数学计算,因此查询某一个特定的key-value键值对的时间复杂度为O(1)。
举个例子(只是帮助理解),还是上述的list_a和list_b。我们将所有的元素当作key, value可以随意选取,假设映射规则是 key / 11,那么list_a中的11映射为1,22映射为2,33映射为3,44映射为4,55映射为5,list_b中的22映射为2,11映射为1,55映射为5,44映射为4,33映射为3.于是,只需要一次遍历,我们就能知道list_a中的元素和list_b中的元素是一样的。
HashMap的遍历要使用迭代器或增强for循环。
迭代器
Map map = new HashMap();
Iterator iter = map.entrySet().iterator();
while (iter.hasNext()) {
Map.Entry entry = (Map.Entry) iter.next();
Object key = entry.getKey();
Object val = entry.getValue();
}
增强for循环
Map<String, String> map = new HashMap<String, String>();
for (String key : map.keySet()) {
map.get(key);
}
或者
Map<String, String> map = new HashMap<String, String>();
for (Entry<String, String> entry : map.entrySet()) {
entry.getKey();
entry.getValue();
}
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map.Entry;
public class HashMapTest {
public static void main(String[] args) {
HashMap<String, String> map = new HashMap<>();
map.put("zhang", "31");//存放键值对
System.out.println(map.containsKey("zhang"));//键中是否包含这个数据
System.out.println("=========================");
System.out.println(map.get("zhang"));//通过键拿值
System.out.println("=========================");
System.out.println(map.isEmpty());//判空
System.out.println(map.size());
System.out.println("=========================");
System.out.println(map.remove("zhang"));//从键值中删除
System.out.println("=========================");
map.put("zhang", "31");
System.out.println("=========================");
for (String key : map.keySet()) {
System.out.println(key);
}
System.out.println("=========================");
for (String values : map.values()) {
System.out.println(values);
}
System.out.println("=========================");
map.clear();
for (Entry<String, String> entry : map.entrySet()) {
String key = entry.getKey();
String value = entry.getValue();
System.out.println(key + "," + value);
}
System.out.println("=========================");
// you can not remove item in map when you use the iterator of map
// for(Entry<String,String> entry : map.entrySet()){
// if(!entry.getValue().equals("1")){
// map.remove(entry.getKey());
// }
// }
// if you want to remove items, collect them first, then remove them by
// this way.
List<String> removeKeys = new ArrayList<String>();
for (Entry<String, String> entry : map.entrySet()) {
if (!entry.getValue().equals("1")) {
removeKeys.add(entry.getKey());
}
}
for (String removeKey : removeKeys) {
map.remove(removeKey);
}
for (Entry<String, String> entry : map.entrySet()) {
String key = entry.getKey();
String value = entry.getValue();
System.out.println(key + "," + value);
}
System.out.println("=========================");
}
}
HashSet
HashSet是Java集合Set的一个实现类,Set是一个接口,其实现类除HashSet之外,还有TreeSet,并继承了Collection。
构造方法:HashSet set = new HashSet();
添加元素:
hashset.add(E e):返回boolean型,如果此 set 中尚未包含指定元素,则添加指定元素;如果此 set 已包含该元素,则该调用不更改 set 并返回 false。
删除元素:
hashset.clear():从此 set 中移除所有元素。
hashset.remove(Object o):如果指定元素存在于此 set 中,则将其移除。
hashset.isEmpty():如果此 set 不包含任何元素,则返回 true。
hashset.contains(Object o):如果此 set 包含指定元素,则返回 true。
hashset.size():返回此 set 中的元素的数量(set 的容量)。
HashSet是通过HashMap来实现的,HashMap通过hash(key)来确定存储的位置,是不具备存储顺序性的,因此HashSet遍历出的元素也并非按照插入的顺序。
HashSet遍历-迭代器:
Iterator it = setString.iterator();
while (it.hasNext()) {
System.out.println(it.next());
}
TreeSet
TreeSet简介
TreeSet 是一个有序的集合,它的作用是提供有序的Set集合。它继承于AbstractSet抽象类,实现了NavigableSet, Cloneable, java.io.Serializable接口。
TreeSet 继承于AbstractSet,所以它是一个Set集合,具有Set的属性和方法。
TreeSet 实现了NavigableSet接口,意味着它支持一系列的导航方法。比如查找与指定目标最匹配项。
TreeSet 实现了Cloneable接口,意味着它能被克隆。
TreeSet 实现了java.io.Serializable接口,意味着它支持序列化。
TreeSet是基于TreeMap实现的。TreeSet中的元素支持2种排序方式:自然排序 或者 根据创建TreeSet 时提供的 Comparator 进行排序。这取决于使用的构造方法。
TreeSet为基本操作(add、remove 和 contains)提供受保证的 log(n) 时间开销。
另外,TreeSet是非同步的。 它的iterator 方法返回的迭代器是fail-fast的。
TreeSet是有序的Set集合,因此支持add、remove、get等方法。
TreeSet不支持快速随机遍历,只能通过迭代器进行遍历!
TreeSet可以保证集合中元素的唯一性和有序性,当集合中的元素不能比较时,实现comparable接口方法。
知识总结基本到此为止,中等难度的题目要么是在对时间或者空间进行优化,要么是数学问题等等,还有一部分树的题目,经典的像按层次输出二叉树、排序树。一部分链表相关题目使用了双指针“链表找公共节点X型”,或者“寻找两个链表第一个公共节点Y型”使用了栈(栈的用法似乎只能用C++实现,Java不支持Stack<ListNode>这种用法)。
目前来看关于编程我还太差,不足以应对大厂面试中手撕代码的问题,真的很崩溃为什么测试岗代码能力要求也这么高.如果宁波银行测试岗能收我我愿意半年茹素。不开玩笑地话波行真的是我最想去的地方了,太向往了,按照我这20多年来的经验来看,我越想得到什么越不会得到,失望多了也不太敢期待了,随缘一点吧,秋招不顺利的话就准备准备考公或者回家考研了。