単一リンクリスト
1.リンクリスト要素を削除します
class Solution {
public ListNode removeElements(ListNode head, int val) {
if (head == null) return null;
ListNode cur = head;
ListNode pre = cur;
while (cur != null) {
if (cur.val == val) {
pre.next = cur.next;
}else {
pre = cur;
}
cur = cur.next;
}
if(head.val == val) {
head = head.next;
}
return head;
}
}
2.逆リンクリスト
//改变前后节点指向
public ListNode reverseList(ListNode head) {
ListNode cur = head;
ListNode pre = null;
while(cur != null) {
ListNode curNext = cur.next;
if(curNext == null) {
head = cur;
}
cur.next = pre;
pre = cur;
cur = curNext;
}
return head;
}
方法2:
//头插法
public ListNode reverseList1 (ListNode head) {
if(head == null) {
return head;
}
ListNode cur = head.next;
head.next = null;
while(cur != null) {
ListNode curNext = cur.next;
cur.next = head;
head = cur;
cur = curNext;
}
return head;
}
3.リンクリストの中間ノード
public ListNode middleNode(ListNode head) {
//快慢指针
ListNode fast = head;
ListNode slow = head;
while(fast != null && fast.next != null) {
fast = fast.next.next;
slow = slow.next;
}
return slow;
}
4.リンクリストの下からk番目のノード
//第一次
public ListNode FindKthToTail(ListNode head,int k) {
ListNode fast = head;
ListNode slow = head;
int count = 0;
int a = k;
while(a != 0 && fast != null) {
fast = fast.next;
a--;
count++;
}
while(fast != null) {
fast = fast.next;
slow = slow.next;
count++;
}
if(count < k) return null;
return slow;
}
方法2:
//优化
public ListNode FindKthToTail1(ListNode head,int k) {
ListNode fast = head;
ListNode slow = head;
while(k != 0) {
if(fast != null){
fast = fast.next;
k--;
}else {
return null;
}
}
while(fast != null) {
fast = fast.next;
slow = slow.next;
}
return slow;
}
5.2つの順序付けられたリンクリストをマージします
public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
ListNode head = new ListNode(-1);
ListNode tmp = head;
while(l1 != null && l2 != null) {
if(l2.val <= l1.val) {
tmp.next = l2;
l2 = l2.next;
}else {
tmp.next = l1;
l1 = l1.next;
}
tmp = tmp.next;
}
if(l2 == null) {
tmp.next = l1;
}else {
tmp.next = l2;
}
head = head.next;
return head;
}
6、リンクリストの分割
点トピックリンクにジャンプします
public ListNode partition(ListNode pHead, int x) {
ListNode headA = new ListNode(x);
ListNode headB = new ListNode(x);
ListNode a = headA;
ListNode b = headB;
ListNode cur = pHead;
while(cur != null) {
if(cur.val < x) {
a.next = cur;
a = a.next;
}else {
b.next = cur;
b = b.next;
}
cur = cur.next;
}
a.next = headB.next;
b.next = null;
headA = headA.next;
return headA;
}
7.リンクリスト内の重複ノードを削除します
public ListNode deleteDuplication1(ListNode pHead){
if(pHead == null) return null;
ListNode newHead = new ListNode(-1);
ListNode tmp = newHead;
ListNode cur = pHead;
while(cur != null) {
if(cur.next != null && cur.val == cur.next.val) {
while(cur.next != null && cur.val == cur.next.val) {
cur = cur.next;
}
}else {
tmp.next = cur;
tmp = tmp.next;
}
cur = cur.next;
}
newHead = newHead.next;
tmp.next = null;
return newHead;
}
8.リンクリストの回文構造
public boolean chkPalindrome(ListNode A) {
//先快慢指针找到中间节点
ListNode fast = A;
ListNode slow = A;
while(fast != null && fast.next != null) {
fast = fast.next.next;
slow = slow.next;
}
//然后翻转中间节点后面节点的指向
ListNode cur = slow.next;
slow.next =null;
while(cur != null) {
ListNode curNext = cur.next;
cur.next = slow;
slow = cur;
cur = curNext;
}
//最后从后往前 以及 从前往后 比较每个节点的值
while(slow != null) {
if(slow.val != A.val) {
return false;
}
slow = slow.next;
A = A.next;
}
return true;
}
9.リンクリストの交差
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
ListNode curA = headA;
ListNode curB = headB;
int count = size(headA)-size(headB);
if(count > 0) {
while(count != 0) {
curA = curA.next;
count--;
}
}else {
while(count != 0) {
curB = curB.next;
count++;
}
}
while(curA != curB) {
if(curA == null) return null;
curA = curA.next;
curB = curB.next;
}
return curA;
}
public int size(ListNode head) {
if(head == null) return 0;
int count = 0;
ListNode cur = head;
while(cur != null) {
cur = cur.next;
count++;
}
return count;
}
10.循環リンクリスト
public boolean hasCycle(ListNode head) {
ListNode fast = head;
ListNode slow = head;
do {
if(fast == null || fast.next == null) return false;
fast = fast.next.next;
slow = slow.next;
}while(slow != fast);
return true;
}
11.循環リンクリストII
public ListNode detectCycle(ListNode head) {
ListNode fast = head;
ListNode slow = head;
do {
if(fast == null || fast.next == null) return null;
fast = fast.next.next;
slow = slow.next;
}while(slow != fast);
slow = head;
while(slow != fast) {
slow = slow.next;
fast = fast.next;
}
return fast;
}
12.中間ノードを削除します
public void deleteNode(ListNode node) {
node.val = node.next.val;
node.next = node.next.next;
}
13.リンクリストのローテーション
//时间会慢
public ListNode rotateRight2(ListNode head, int k) {
if(head == null) return null;
if(k == 0) return head;
ListNode fast = head;
ListNode slow = head;
while(k != 0) {
if(fast.next != null) {
fast = fast.next;
}else {
fast = head;
}
k--;
}
if(fast == slow) return head;
while(fast.next != null) {
fast = fast.next;
slow = slow.next;
}
ListNode tmp = slow.next;
slow.next = null;
fast.next = head;
head = tmp;
return head;
}
方法2:
//快
public ListNode rotateRight(ListNode head, int k) {
if(head == null) return null;
ListNode cur = head;
int count = 1;
while(cur.next != null) {
cur = cur.next;
count++;
}
cur.next = head;
int step = count-k%count;
while(step != 0) {
head = head.next;
step--;
}
cur = head;
while(count != 1) {
cur = cur.next;
count--;
}
cur.next = null;
return head;
}