第3节.pptx
1 单链表与双链表的简单练习
题目1:单链表和双链表如何反转
01 单链表反转

//反转链表 public static ListNode reverseListNode(ListNode head) { if (head == null || head.next == null) { return head; } ListNode pre = null; ListNode next = null; while (head != null) { next = head.next; head.next = pre; pre = head; head = next; } return pre; } /*以下代码为对数器,测试单链表反转*/ //对数器,用List容器实现链表反转 public static ListNode comarator(ListNode head) { if (head == null || head.next == null) { return head; } List<ListNode> list = new ArrayList<>(); while (head != null) { list.add(head); head = head.next; } list.get(0).next = null; for (int i = 1; i < list.size(); i++) { list.get(i).next = list.get(i - 1); } return list.get(list.size() - 1); } //生成随机链表 public static ListNode generateRandomListNode(int listLength, int maxValue) { ListNode cur = new ListNode(((int) (Math.random() * maxValue) - (int) (Math.random() * maxValue)), null); //保证生成的链表至少有1个节点 ListNode head = cur; int length = (int) (Math.random() * listLength + 1); for (int i = 0; i < length - 1; i++) { cur.next = new ListNode(((int) (Math.random() * maxValue) - (int) (Math.random() * maxValue)), null); cur = cur.next; } return head; } 检查两个链表结构是否一致 public static boolean check(ListNode head1, ListNode head2) { if (head1 == null && head2 == null) { return true; } if (head1 != null ^ head2 != null) { return false; } while (head1 != null && head2 != null) { if (head1.data != head2.data) { return false; } head1 = head1.next; head2 = head2.next; if (head1 != null ^ head2 != null) { return false; } } return true; } //打印单链表 public static void printListNode(ListNode head) { if (head == null) { return; } while (head != null) { System.out.print(head.data + " "); head = head.next; } System.out.println(); } //复制一个单链表结构 public static ListNode copyListNode(ListNode head) { if (head == null) { return head; } ListNode ans = new ListNode(head.data, null); ListNode cur = ans; while (head.next != null) { cur.next = new ListNode(head.next.data, null); cur = cur.next; head = head.next; } return ans; }
02 双链表反转

/*双链表反转*/ public static DoubleListNode reverseDoubleListNode(DoubleListNode head) { if (head == null || head.next == null) { return head; } DoubleListNode pre = null; DoubleListNode next = null; while (head != null) { next = head.next; head.next = pre; head.prev = next; pre = head; head = next; } return pre; } /*以下代码为对数器,用于测试*/ public static DoubleListNode comparator(DoubleListNode head) { if (head == null || (head.next == null && head.prev == null)) { return head; } List<DoubleListNode> list = new ArrayList<>(); while (head != null) { list.add(head); head = head.next; } list.get(0).next = null; list.get(0).prev = list.get(1); for (int i = 1; i < list.size(); i++) { list.get(i).next = list.get(i - 1); if (i == list.size() - 1) { list.get(i).prev = null; } else { list.get(i).prev = list.get(i + 1); } } return list.get(list.size() - 1); } public static DoubleListNode generateRandomDoubleListNode(int maxLength, int maxValue) { //保证至少有一个节点 int length = (int) (Math.random() * maxLength + 1); DoubleListNode head = new DoubleListNode((int) (Math.random() * maxValue + 1) - (int) (Math.random() * maxValue + 1), null, null); DoubleListNode cur = head; for (int i = 0; i < length - 1; i++) { DoubleListNode next = new DoubleListNode((int) (Math.random() * maxValue + 1) - (int) (Math.random() * maxValue + 1), null, null); cur.next = next; next.prev = cur; cur = next; } return head; } public static DoubleListNode copyDoubleListNode(DoubleListNode head) { if (head == null) { return null; } DoubleListNode ans = new DoubleListNode(head.data, null, null); DoubleListNode cur = ans; while (head.next != null) { DoubleListNode next = new DoubleListNode(head.next.data, null, null); cur.next = next; next.prev = cur; cur = next; head = head.next; } return ans; } public static boolean check(DoubleListNode head1, DoubleListNode head2) { if (head1 == null && head2 == null) { return true; } if (head1 != null ^ head2 != null) { return false; } DoubleListNode end1 = null; DoubleListNode end2 = null; //正向比较 while (head1 != null && head2 != null) { if (head1.data != head1.data) { return false; } end1 = head1; end2 = head2; head1 = head1.next; head2 = head2.next; if (head1 != null ^ head2 != null) { return false; } } //逆向比较 while (end1 != null && end2 != null) { if (end1.data != end1.data) { return false; } end1 = end1.prev; end2 = end2.prev; if (end1 != null ^ end2 != null) { return false; } } return true; } public static void printDoubleListNode(DoubleListNode head) { if (head == null) { return; } DoubleListNode end = null; while (head != null) { System.out.print(head.data+" "); end = head; head = head.next; } System.out.println(); while (end != null) { System.out.print(end.data+" "); end = end.prev; } System.out.println(); }
题目2:把给定值都删除
/*把给定值都删除
*/
public static ListNode deleteGivenValue(ListNode head, int value) {
while (head != null && head.data == value) {
head = head.next;
}
if (head == null) {
return null;
}
ListNode cur = head;
ListNode next = cur.next;
while (next != null) {
cur.next = null;
if (next.data != value) {
cur.next = next;
cur = next;
}
next = next.next;
}
return head;
}
/*以下为对数器,用于测试*/
public static ListNode comparator(ListNode head, int value) {
if (head == null) {
return null;
}
LinkedList<Integer> list = new LinkedList<>();
while (head != null) {
list.add(Integer.valueOf(head.data));
head = head.next;
}
int count = 0;
for (int i = 0; i < list.size(); i++) {
if (list.get(i) == value) {
count++;
}
}
for (int i = 0; i < count; i++) {
list.remove(Integer.valueOf(value));
}
if (list.size() == 0) {
return null;
}
head = new ListNode(list.get(0));
ListNode cur = head;
for (int i = 1; i < list.size(); i++) {
ListNode next = new ListNode(list.get(i));
cur.next = next;
cur = next;
}
return head;
}
public static ListNode generateRandomListNode(int maxLength, int maxValue, int value) {
int length = (int) (Math.random() * (maxLength + 1));
if (length == 0) {
return null;
}
ListNode head = new ListNode((int) (Math.random() * maxValue + 1) - (int) (Math.random() * maxValue + 1));
ListNode cur = head;
for (int i = 0; i < length - 1; i++) {
double random = Math.random();
ListNode next = null;
if (random < 0.5) {
next = new ListNode((int) (Math.random() * maxValue + 1));
} else {
next = new ListNode(value);
}
cur.next = next;
cur = next;
}
return head;
}
public static boolean check(ListNode head1, ListNode head2) {
if (head1 == null && head2 == null) {
return true;
}
if (head1 != null ^ head2 != null) {
return false;
}
while (head1 != null && head2 != null) {
if (head1.data != head2.data) {
return false;
}
head1 = head1.next;
head2 = head2.next;
if (head1 != null ^ head2 != null) {
return false;
}
}
return true;
}
public static ListNode copyListNode(ListNode head) {
if (head == null) {
return head;
}
ListNode ans = new ListNode(head.data);
ListNode cur = ans;
while (head.next != null) {
cur.next = new ListNode(head.next.data);
cur = cur.next;
head = head.next;
}
return ans;
}
public static void printListNode(ListNode head) {
if (head == null) {
return;
}
while (head != null) {
System.out.print(head.data + " ");
head = head.next;
}
System.out.println();
}
2 栈和队列
题目1:双链表实现栈和队列
01 双链表实现栈
static class DoubleListNode<T> {
public T data;
public DoubleListNode<T> prev;
public DoubleListNode<T> next;
public DoubleListNode(T data) {
this.data = data;
}
}
static class MyStack<T> {
private DoubleListNode<T> head;
public MyStack() {
}
//push
public void push(T num) {
if (head == null) {
head = new DoubleListNode<>(num);
} else {
DoubleListNode next = new DoubleListNode<>(num);
head.next = next;
next.prev = head;
head = next;
}
}
//pop
public T pop() {
if (head == null) {
return null;
}
T data = head.data;
head = head.prev;
return data;
}
//isEmpty
public boolean isEmpty() {
return head == null;
}
}
02 双链表实现队列
static class MyDeque<T> {
DoubleListNode<T> head;
DoubleListNode<T> end;
public MyDeque() {
}
public void addFirst(T num) {
DoubleListNode<T> cur = new DoubleListNode(num);
if (head == null) {
head = cur;
end = cur;
} else {
cur.next = head;
head.prev = cur;
head = cur;
}
}
public void addLast(T num) {
DoubleListNode<T> cur = new DoubleListNode(num);
if (head == null) {
head = cur;
end = head;
} else {
cur.prev = end;
end.next = cur;
end = cur;
}
}
public T popFirst() {
if (head == null) {
return null;
}
T data = head.data;
if (head == end) {
head = null;
end = null;
} else {
head = head.next;
head.prev = null;
}
return data;
}
public T popLast() {
if (end == null) {
return null;
}
T data = end.data;
if (end == head) {
end = null;
head = null;
} else {
end = end.prev;
end.next = null;
}
return data;
}
public boolean isEmpty() {
return head == null && end == null;
}
}
题目2:数组实现栈和队列
01 数组实现栈
static class MyStack {
private int[] arr;
private static final int DEAUFAL_LENGTH = 16;
private static int endIndex;
private static int length;
public MyStack() {
}
public void push(int num) {
if (arr == null) {
arr = new int[DEAUFAL_LENGTH];
length = arr.length;
endIndex = 0;
arr[endIndex++] = num;
} else {
if (endIndex == length) {
length = length + (length >> 1);
int[] newArr = new int[length];
System.arraycopy(arr, 0, newArr, 0, arr.length);
arr = newArr;
}
arr[endIndex++] = num;
}
}
public Integer pop() {
if (arr == null && endIndex == 0) {
return null;
}
return arr[--endIndex];
}
public boolean isEmpty() {
return endIndex == 0;
}
}
02 数组实现队列
/**
* 数组实现队列
*/
static class MyQueue {
private final int[] arr;
private final int length;
private int size;
private int pushIndex;
private int popIndex;
private MyQueue(int length) {
this.length = length;
arr = new int[length];
pushIndex = 0;
popIndex = 0;
}
public static MyQueue getQueue(int length) {
return new MyQueue(length);
}
public void push(int num) throws RuntimeException {
if (size == length) {
throw new RuntimeException("队列已满,添加失败");
}
arr[pushIndex] = num;
size++;
pushIndex = nextIndex(pushIndex);
}
public Integer pop() throws RuntimeException {
if (size == 0) {
return null;
}
int ans = arr[popIndex];
popIndex = nextIndex(popIndex);
size--;
return ans;
}
public boolean isEmpty() {
return size == 0;
}
private int nextIndex(int index) {
return index < length - 1 ? index + 1 : 0;
}
}
题目3:实现一个特殊的栈,在基本功能的基础上,再实现返回栈中最小元素的功能
/*
* 实现一个特殊的栈,在基本功能的基础上,再实现返回栈中最小元素的功能
1)pop、push、getMin操作的时间复杂度都是 O(1)。
2)设计的栈类型可以使用现成的栈结构。
*/
static class MyStack {
private Stack<Integer> stack;
private Stack<Integer> minValueStack;
private int minValue;
public MyStack() {
stack = new Stack<>();
minValueStack = new Stack<>();
}
public void push(int num) {
if (minValueStack.isEmpty()) {
minValue = num;
} else {
minValue = minValueStack.peek() < num ? minValueStack.peek() : num;
}
stack.push(num);
minValueStack.push(minValue);
}
public Integer pop() {
if (stack.isEmpty()) {
return null;
}
minValueStack.pop();
return stack.pop();
}
public Integer getMin() {
if (minValueStack.isEmpty()) {
return null;
}
return minValueStack.peek();
}
public boolean isEmpty(){
return stack.isEmpty();
}
}
题目4:用栈结构实现队列
//如何用栈结构实现队列结构
static class MyQueue {
private Stack<Integer> pushStack;
private Stack<Integer> popStack;
public MyQueue() {
pushStack = new Stack<>();
popStack = new Stack<>();
}
public void add(int num) {
pushStack.push(num);
}
public Integer poll() {
if (popStack.empty() && pushStack.empty()) {
return null;
}
pushStackPollToPopStack();
return popStack.pop();
}
public Integer peek() {
if (popStack.empty() && pushStack.empty()) {
return null;
}
pushStackPollToPopStack();
return popStack.peek();
}
public boolean isEmpty() {
return pushStack.isEmpty() && popStack.isEmpty();
}
private void pushStackPollToPopStack() {
if (popStack.empty()) {
while (!pushStack.empty()) {
popStack.push(pushStack.pop());
}
}
}
}
题目5:用队列结构实现栈
static class MyStack {
private Queue<Integer> pushQueue;
private Queue<Integer> popQueue;
public MyStack() {
pushQueue = new LinkedList<>();
popQueue = new LinkedList<>();
}
public void push(int num) {
pushQueue.add(num);
}
public Integer pop() {
while (pushQueue.size() > 1) {
popQueue.add(pushQueue.poll());
}
Integer ans = pushQueue.poll();
Queue<Integer> temp = pushQueue;
pushQueue = popQueue;
popQueue = temp;
return ans;
}
public Integer peek() {
while (pushQueue.size() > 1) {
popQueue.add(pushQueue.poll());
}
Integer ans = pushQueue.poll();
popQueue.add(ans);
Queue<Integer> temp = pushQueue;
pushQueue = popQueue;
popQueue = temp;
return ans;
}
public boolean isEmpty() {
return pushQueue.isEmpty();
}
}
3 递归时间复杂度估算
