单链表和双链表
1 单链表和双链表如何反转
2 把给定的值都删除
public class ReverseList {
public static class Node{
public int value;
public Node next;
public Node(int data){
value = data;
}
}
public static class DoubleNode{
public int value;
public DoubleNode last;
public DoubleNode next;
public DoubleNode(int data){
value = data;
}
}
public static Node reverseLinkedList(Node head){
Node pre = null;
Node next = null;
while(head != null){
next = head.next;
head.next = pre;
pre = head;
head = next;
}
return pre;
}
public static DoubleNode reverseDoubleList(DoubleNode head){
DoubleNode pre = null;
DoubleNode next = null;
while(head != null){
next = head.next;
head.next = pre;
head.last = next;
pre = head;
head = next;
}
return pre;
}
}
public static Node removeValue(Node head,int num){
while(head != null){
if(head.value != num){
break;
}
head = head.next;
}
Node pre = head;
Node cur = head;
while(cur != null){
if(cur.value == num){
pre.next = cur.next;
}else{
pre = cur;
}
cur = cur.next;
}
return head;
}
栈和队列的实际实现
- 双向链表实现
- 数组实现
public static class MyQueue{
private int[] arr;
private int pushi;
private int polli;
private int size;
private final int limit;
public MyQueue(int l){
arr = new int[l];
pushi = 0;
polli = 0;
size = 0;
limit = l;
}
public void push(int value){
if(size == limit){
throw new RuntimeException("队满");
}
size++;
arr[pushi] = value;
pushi = nextIndex(pushi);
}
public int pop(){
if(size == 0){
throw new RuntimeException("队空");
}
size--;
int ans = arr[polli];
polli = nextIndex(polli);
return ans;
}
private int nextIndex(int i) {
return i < limit - 1 ? i + 1 : 0;
}
}
栈和队列常见面试题
//做一个栈实现push,pop,getmin方法
public static class MyStack{
private Stack<Integer> stackData;
private Stack<Integer> stackMin;
public MyStack(){
stackData = new Stack<>();
stackMin = new Stack<>();
}
public void push(int newNum){
if(stackMin.isEmpty()){
stackMin.push(newNum);
}else if(newNum < getMin()){
stackMin.push(newNum);
}else {
stackMin.push(stackMin.peek());
}
stackData.push(newNum);
}
public int pop(){
if(stackData.isEmpty()){
throw new RuntimeException("栈空");
}
stackMin.pop();
return stackData.pop();
}
private int getMin() {
if(stackMin.isEmpty()){
throw new RuntimeException("栈空");
}
return stackMin.peek();
}
}
//用栈实现队列
public static class TwoStacksQueue{
public Stack<Integer> stackPush;
public Stack<Integer> stackPop;
public TwoStacksQueue(){
stackPop = new Stack<>();
stackPush = new Stack<>();
}
private void pushToPop(){
if(stackPop.empty()){
while(!stackPush.empty()){
stackPop.push(stackPush.pop());
}
}
}
public void add(int pushInt){
stackPush.push(pushInt);
pushToPop();
}
public int poll(){
if(stackPop.empty() && stackPush.empty()){
throw new RuntimeException("队空");
}
pushToPop();
return stackPop.pop();
}
public int peek(){
if(stackPop.empty() && stackPush.empty()){
throw new RuntimeException("队空");
}
pushToPop();
return stackPop.peek();
}
}
//用队列实现栈
递归
只要满足T(N) = a * T(N/b) + O(N^d),则递归的时间复杂度为:
- logb(a) > d 时间复杂度为O(N^logb(a))
- logb(a) < d 时间复杂度为O(N^d)
- logb(a) = d 时间复杂度为O(N^d * log(N))
哈希表
HashMap , HashSet
哈希表的增删改查时间复杂度为O(1)的。
HashMap , HashSet唯一的区别是有无伴随数据,实际结构一样。
放入哈希表的东西,如果是基础类型,内部按值传递,内存占用是原数据的大小。
如果是其他类型,内部按地址传递。
有序表
TreeMap