感觉链表这东西还是要多练,但是实在没做什么双链表的题。。理解的不好。
哈希表的简单介绍
- 哈希表在使用层面上可以理解为一种集合结构;
- 如果只有key,没有伴随数据value,可以使用HashSet结构;
- 如果既有key,又有伴随数据value,可以使用HashMap结构;
- 有无伴随数据,是HashMap和HashSet唯一的区别,底层的实际结构是一回事;
- 使用哈希表**增(put)、删(remove)、改(put)|和查(get)**的操作,可以认为时间复杂度为O(1),但是常数时间比较大。
- 放入哈希表的东西,如果是基础类型,内部按值传递,内存占用就是这个东西的大小;
- 放入哈希表的东西,如果不是基础类型,内部按引用传递,内存占用是这个东西内存地址的大小。
有序表的简单介绍
put(K key,V value)//将一个(key,value)记录加入到表中,或者将key的记录更新出value
treeMap.get(5); //获取有序表中,key为5的value的值
treeMap.containsKey(5); //判断有序表中是否存在Key为5的键值对
treeMap.firstKey(5);//获取有序表中最小的key
treeMap.lastKey(5);//获取有序表中最大的key
treeMap.floorKey(5);//获取表中所有小于等于5的key中,最接近的那个数(如果存入过这个key,则返回key)
treeMap.floorKey(5);//获取表中所有大于等于5的key中,最接近的那个数(如果存入过这个key,则返回key)
treeMap.remove(5);//删除有序表中,key为5的键值对
//以上所有操作时间复杂度都是O(logN),N为有序表含有的记录数
- 有序表在使用层面上可以理解为一种集合结构;
- 如果只有key,没有伴随数据value,可以使用TreeSet结构;
- 如果既有key,又有伴随数据value,可以使用TreeMap结构;
- 有无伴随数据,是TreeMap和TreeSet唯一的区别,底层的实际结构是一回事;
- 红黑树、AVL树、size-balance-tree和跳表等都属于有序表结构,只是底层具体实现不同;
- 放入有序表的东西,如果是基础类型,内部按值传递,内存占用就是这个东西的大小;
- 放入有序表的东西,如果不是基础类型,必须提供比较器,内部按引用传递,内存占用是这个东西内存地址的大小。
- 不管是什么底层具体实现,只要是有序表,都有以上固定的基本功能和固定的时间复杂度。
- 放入哈希表的东西,如果不是基础类型,内部按引用传递,内存占用是这个东西内存地址的大小。
单链表增删改获取
public class linklist {
class node {
int val;
node next;
public node(int val) {
this.val = val;
}
node(int val, node next) {
this.val = val;
this.next = next;
}
}
/** Initialize your data structure here. */
private node head;
private int size;
/**
* Get the value of the index-th node in the linked list. If the index is
* invalid, return -1.
*/
public int get(int index) {
if (index < 0 || index >= size) {
return -1;
}
node cur = head;
for (int i = 0; i < index; i++) {
cur = cur.next;
}
return cur.val;
}
/**
* Add a node of value val before the first element of the linked list. After
* the insertion, the new node will be the first node of the linked list.
*/
public void HeadAdd(int val) {
node cur = head;
head = new node(val);
head.next = cur;
size++;
}
/** Append a node of value val to the last element of the linked list. */
public void TailAdd(int val) {
node newnode = new node(val);
if (head == null) {
head = newnode;
} else {
node cur = head;
while (cur.next != null) {
cur = cur.next;
}
cur.next = newnode;
}
size++;
}
/**
* Add a node of value val before the index-th node in the linked list. If index
* equals to the length of linked list, the node will be appended to the end of
* linked list. If index is greater than the length, the node will not be
* inserted.
*/
public void IndexAdd(int index, int val) {
if (index > size) {
return;
}
if (index <= 0) {
HeadAdd(val);
return;
}
node cur = head;
for (int i = 0; i < index - 1; i++) {
cur = cur.next;
}
node newnode = new node(val);
newnode.next = cur.next;
cur.next = newnode;
size++;
}
/** Delete the index-th node in the linked list, if the index is valid. */
public void delete(int index) {
if (index < 0 || index >= size) {
return;
}
size--;
if (index == 0) {
head = head.next;
}
node cur = head;
for (int i = 0; i < index - 1; i++) {
cur = cur.next;
}
cur.next = cur.next.next;
}
public void reverse() {
node newlist = null;
while(head.next != null) {
node temp = head.next;
head.next = newlist;
newlist = head;
head = temp;
}
}
}
用栈判断一个链表是否为回文结构
public static class Node {
public int value;
public Node next;
public Node(int data) {
this.value = data;
}
}
// need n extra space
public static boolean isPalindrome1(Node head) {
Stack<Node> stack = new Stack<Node>();
Node cur = head;
while (cur != null) {
stack.push(cur);
cur = cur.next;
}
while (head != null) {
if (head.value != stack.pop().value) {
return false;
}
head = head.next;
}
return true;
}