13:用双链表结构实现双端队列
// 使用双链表实现双端队列
public class DoubleLinkedListToDeque<V> {
public static class Node<V> {
V value;
Node<V> next;
Node<V> last;
public Node(V value) {
this.value = value;
}
}
Node<V> head;
Node<V> tail;
int usedSize;
public DoubleLinkedListToDeque() {
head = null;
tail = null;
usedSize = 0;
}
public boolean isEmpty() {
return this.usedSize == 0;
}
public int size() {
return this.usedSize;
}
public void pushHead(V value) {
Node<V> cur = new Node<>(value);
if(head == null) {
tail = cur;
head = cur;
}else {
cur.next = head;
head.last = cur;
head = cur;
}
usedSize++;
}
public void pushTail(V value) {
Node<V> cur = new Node<>(value);
if(head == null) {
tail = cur;
head = cur;
}else {
tail.next = cur;
cur.last = tail;
tail = cur;
}
usedSize++;
}
public V popHead() {
if(this.head == null) {
return null;
}
V cur = this.head.value;
if(this.head == this.tail) {
this.head = null;
this.tail = null;
}else {
head = head.next;
// 别忘了这一步
head.last = null;
}
usedSize--;
return cur;
}
public V popTail() {
if(this.head == null) {
return null;
}
V cur = this.tail.value;
if(this.head == this.tail) {
this.head = null;
this.tail = null;
}else {
tail = tail.last;
// 别忘了这一步
tail.next = null;
}
usedSize--;
return cur;
}
public V peekHead() {
return this.isEmpty() ? null : this.head.value;
}
public V peekTail() {
return this.isEmpty() ? null : this.tail.value;
}
}
14:K个节点的组内逆序调整
给定一个单链表的头节点head,和一个正数k
实现k个节点的小组内部逆序,如果最后一组不够k个就不调整
例子:
调整前:1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7 -> 8,k = 3
调整后:3 -> 2 -> 1 -> 6 -> 5 -> 4 -> 7 -> 8
// K 个一组翻转链表
public class ReverseNodesInKGroup {
public static class ListNode {
int val;
ListNode next;
ListNode() {
}
ListNode(int val) {
this.val = val;
}
ListNode(int val, ListNode next) {
this.val = val;
this.next = next;
}
}
public ListNode reverseKGroup(ListNode head, int k) {
ListNode start = head;
ListNode end = getKGroupEnd(start , k);
if(end == null) {
return head;
}
// 说明有第一段
head = end;
reverse(start, end);
while(start.next != null) {
ListNode lastEnd = start;
start = lastEnd.next;
end = getKGroupEnd(start,k);
if(end == null) {
return head;
}
// 说明有第二段
reverse(start, end);
lastEnd.next = end;
}
return head;
}
// 得到一段区域的末尾节点
public static ListNode getKGroupEnd(ListNode start, int k) {
for (int i = 1; start != null && i < k; i++) {
start = start.next;
}
return start;
}
// 把这一段进行反转
public static void reverse(ListNode start, ListNode end) {
ListNode pre = null;
ListNode cur = start;
ListNode next = null;
while(pre != end) {
next = cur.next;
cur.next = pre;
pre = cur;
cur = next;
}
start.next = cur;
}
}