/**
* Created with IntelliJ IDEA.
* Description:
* User: zhuzhuzhuchao
* Date: 2022-01-05
* Time: 17:03
*/
public class TestDemo {
public static void main(String[] args) {
MyLinkedList myLinkedList = new MyLinkedList();
MyLinkedList myLinkedList1 = new MyLinkedList();
myLinkedList.addLast(12);
myLinkedList.addLast(23);
myLinkedList.addLast(34);
myLinkedList.addLast(45);
myLinkedList.addLast(56);
myLinkedList.display();
// 反向
ListNode ret = myLinkedList.reverseList();
myLinkedList.display2(ret);
// 求链表中间节点
System.out.println(myLinkedList.middleNode().val);
// 找倒数第k个节点
System.out.println(myLinkedList.FindKthToTail(2).val);
System.out.println(myLinkedList.FindKthToTail(5).val);
myLinkedList1.addLast(13);
myLinkedList1.addLast(24);
myLinkedList1.addLast(30);
ListNode ret = mergeTwoLists(myLinkedList.head,myLinkedList1.head);
myLinkedList.display2(ret);
// 链表回文结构
MyLinkedList myLinkedList1 = new MyLinkedList();
myLinkedList1.addLast(1);
myLinkedList1.addLast(2);
myLinkedList1.addLast(2);
myLinkedList1.addLast(1);
myLinkedList1.display();
System.out.println(myLinkedList1.chkPalindrome());
// 相交链表
MyLinkedList myLinkedList = new MyLinkedList();
MyLinkedList myLinkedList1 = new MyLinkedList();
myLinkedList.addLast(1);
myLinkedList.addLast(2);
myLinkedList.addLast(3);
myLinkedList.addLast(4);
myLinkedList1.addLast(12);
myLinkedList1.addLast(12);
myLinkedList1.addLast(12);
myLinkedList1.addLast(12);
createCut(myLinkedList.head,myLinkedList1.head);
System.out.println(getIntersectionNode(myLinkedList.head, myLinkedList1.head).val);
//环形链表判断
MyLinkedList myLinkedList = new MyLinkedList();
myLinkedList.addLast(12);
myLinkedList.addLast(23);
myLinkedList.addLast(34);
myLinkedList.addLast(45);
myLinkedList.addLast(56);
myLinkedList.createLoop();
System.out.println(myLinkedList.hasCycle());
// 环形入口
System.out.println(myLinkedList.func().val);
System.out.println(myLinkedList.detectCycle().val);
}
// 合并两个有序链表
public static ListNode mergeTwoLists(ListNode headA,ListNode headB) {
ListNode newHead = new ListNode(-1);
ListNode tmp = newHead;
while (headA != null && headB != null) {
if (headA.val < headB.val) {
tmp.next = headA;
headA = headA.next;
tmp = tmp.next;
} else {
tmp.next = headB;
headB = headB.next;
tmp = tmp.next;
}
}
if (headA != null) {
tmp.next = headA;
}
if (headB != null) {
tmp.next = headB;
}
return newHead.next;
}
// 输入两个链表找出相交的节点
// 1.如果两个链表相交是Y还是X (Y)next才会相同
// 2.是val域相同还是next域相同 (next)
public static ListNode getIntersectionNode(ListNode headA,ListNode headB) {
if (headA == null || headB == null) {
return null;
}
ListNode pl = headA;// pl指向最长
ListNode ps = headB;// ps指向最短
// 求长度
int lenA = 0;
int lenB = 0;
while (pl != null) {
lenA++;
pl = pl.next;
}
while (ps != null) {
lenB++;
ps = ps.next;
}
// 差值步
int len = lenA = lenB;
if (len < 0) {
pl = headB;
ps = headA;
len = lenB - lenA;
} else {
pl = headA;
ps = headB;
}
// pl先走差值步
for (int i = 0; i < len; i++) {
pl = pl.next;
}
while (ps != pl) {
pl = pl.next;
ps = ps.next;
// if (ps == null || pl == null) {
// return null;
// } 都是同时到达 直接return null
}
return ps;
}
public static void createCut(ListNode headA,ListNode headB) {
headA.next = headB.next;
}
}
import java.util.List;
/**
* Created with IntelliJ IDEA.
* Description:
* User: zhuzhuzhuchao
* Date: 2022-01-05
* Time: 17:04
*/
public class MyLinkedList {
public ListNode head;//链表的头引用
public void createList() {
ListNode listNode1 = new ListNode(12);
ListNode listNode2 = new ListNode(23);
ListNode listNode3 = new ListNode(34);
ListNode listNode4 = new ListNode(45);
ListNode listNode5 = new ListNode(56);
this.head = listNode1;
listNode1.next = listNode2;
listNode2.next = listNode3;
listNode3.next = listNode4;
listNode4.next = listNode5;
}
public void display() {
ListNode cur = this.head;
while (cur != null) {
System.out.print(cur.val + " ");
cur = cur.next;
}
System.out.println();
}
public void display2(ListNode newHead) {
ListNode cur = newHead;
while (cur != null) {
System.out.print(cur.val + " ");
cur = cur.next;
}
System.out.println();
}
public static void main(String[] args) {
ListNode listNode = new ListNode(1);
}
//头插法
public void addFirst(int data) {
ListNode listNode = new ListNode(data);
listNode.next = this.head;
this.head = listNode;
}
//尾插法
// 第一次插入必须判断是不是空
// public void addLast(int data){
// ListNode cur = this.head;
// ListNode listNode = new ListNode(data);
// if (cur == null) {
// cur.val = data;
// } else {
// while (cur.next != null) {
// cur = cur.next;
// }
// cur.next = listNode;
// }
// }
// 博哥写
public void addLast(int data) {
ListNode node = new ListNode(data);
ListNode cur = this.head;
if (this.head == null) {
this.head = node;
} else {
while (cur.next != null) {
cur = cur.next;
}
cur.next = node;
}
}
//任意位置插入,第一个数据节点为0号下标
public void addIndex(int index, int data) {
if (index < 0 || index > size()) {
System.out.println("位置不合法");
return;
}
if (index == 0) {
addFirst(data);
return;
}
if (index == size()) {
addLast(data);
return;
}
ListNode cur = findIndex(index);
ListNode node = new ListNode(data);
node.next = cur.next;
cur.next = node;
}
public ListNode findIndex(int index) {
ListNode cur = this.head;
while (index - 1 != 0) {
cur = cur.next;
index--;
}
return cur;
}
//查找是否包含关键字key是否在单链表当中
public boolean contains(int key) {
ListNode cur = this.head;
while (cur != null) {
if (cur.val == key) {
return true;
}
cur = cur.next;
}
return false;
}
//删除第一次出现关键字为key的节点
public void remove(int key) {
if (this.head == null) {
System.out.println("空");
return;
}
if (this.head.val == key) {
this.head = this.head.next;
return;
}
ListNode prev = searchPerv(key);
if (prev == null) {
System.out.println("没有");
return;
}
ListNode del = prev.next;
prev.next = del.next;
}
public ListNode searchPerv(int key) {
ListNode cur = this.head;
while (cur.next != null) {
if (cur.next.val == key) {
return cur;
}
cur = cur.next;
}
return null;
}
//删除所有值为key的节点
public ListNode removeAllKey(int key) {
if (this.head == null) {
return null;
}
ListNode prev = this.head;
ListNode cur = this.head.next;
while (cur != null) {
if (cur.val == key) {
prev.next = cur.next;
cur = cur.next;
} else {
prev = cur;
cur = cur.next;
}
}
// 最后处理头
if (this.head.val == key) {
this.head = this.head.next;
}
return this.head;
}
//得到单链表的长度
public int size() {
int count = 0;
ListNode cur = this.head;
while (cur != null) {
count++;
cur = cur.next;
}
return count;
}
public void clear() {
// 粗暴
// this.head = null;
while (this.head != null) {
ListNode curNext = this.head.next;
this.head.next = null;
this.head = curNext;
}
this.head = null;
}
// 换方向
public ListNode reverseList() {
if (this.head == null) {
return null;
}
ListNode cur = this.head;
ListNode prev = null;
while (cur != null) {
ListNode curNext = cur.next;
cur.next = prev;
prev = cur;
cur = curNext;
}
return prev;
}
// 给定一个带有头结点 head 的非空单链表,
// 返回链表的中间结点。
// 如果有两个中间结点,则返回第二个中间结点。
public ListNode middleNode() {
if (head == null) {
return null;
}
ListNode fast = this.head;
ListNode slow = this.head;
while (fast != null && fast.next != null) {
fast = fast.next.next;
slow = slow.next;
}
return slow;
}
// 找到倒数第k个节点
// size - k步
// 能不能遍历链表一遍
// fast先走k-1步
public ListNode FindKthToTail(int k) {
ListNode fast = this.head;
ListNode slow = this.head;
if (k <= 0 || this.head == null) {
return null;
}
// for (int i = 0; i < k-1; i++) {
// if (fast.next == null) {
// return null;
// }
// fast = fast.next;
// }
// 博哥
while (k - 1 != 0) {
fast = fast.next;
if (fast == null) {
return null;
}
}
while (fast.next != null) {
fast = fast.next;
slow = slow.next;
}
return slow;
}
// 大于X放前面
public ListNode partition(int x) {
ListNode bs = null;
ListNode be = null;
ListNode as = null;
ListNode ae = null;
ListNode cur = this.head;
while (cur != null) {
if (cur.val < x) {
// 第一次和不是第一次
if (bs == null) {
bs = cur;
be = cur;
} else {
be.next = cur;
be = be.next;
}
} else {
if (as == null) {
as = cur;
ae = cur;
} else {
ae.next = cur;
ae = ae.next;
}
}
cur = cur.next;
}
if (bs == null) {
return as;
}
be.next = as;
if (as != null) {
ae.next = null;
}
return bs;
}
// 删除链表中重复的节点(有序)
public ListNode deleteDuplication() {
ListNode cur = head;
ListNode newHead = new ListNode(-1);
ListNode tmp = newHead;
while (cur != null) {
if (cur.next != null && cur.val == cur.next.val) {
while (cur.next != null && cur.val == cur.next.val) {
cur = cur.next;
}
cur = cur.next;
} else {
tmp.next = cur;
tmp = tmp.next;
cur = cur.next;
}
}
tmp.next = null;
return newHead.next;
}
// 链表的回文结构(字节跳动原题)
// 12 23 34 23 12(回文结构)
// 要求时间O(N) 空间O(1)
// 中点截断,反转后半段,双指针
// 1.奇数while(head != slow) 2.偶数head.next == slow?
public boolean chkPalindrome() {
// 特殊情况
if (this.head == null) {
return true;
}
// 找中间节点 slow
ListNode tmp = this.head;
ListNode slow = this.head;
ListNode fast = this.head;
while (fast != null && fast.next != null) {
slow = slow.next;
fast = fast.next.next;
}
// 反转后半段
ListNode cur = slow.next;
while (cur != null) {
ListNode curNext = cur.next;
cur.next = slow;
slow = cur;
cur = curNext;
}
// 判断回文
while (tmp != slow) {
if (tmp.val != slow.val) {
return false;
}
if (tmp.next == slow) {
return true;
}
tmp = tmp.next;
slow = slow.next;
}
return true;
}
// 环形链表判断
// 定义两个引用:一个块(两步)一个慢(一步)
public boolean hasCycle() {
// 特殊情况
if (head == null) {
return false;
}
ListNode fast = head;
ListNode slow = head;
while (fast != null && fast.next != null) {
fast = fast.next.next;
slow = slow.next;
if (fast == slow) {
return true;
}
}
return false;
}
public void createLoop() {
ListNode cur = this.head;
while (cur.next != null) {
cur = cur.next;
}
cur.next = head.next.next;
}
// 环形入口
public ListNode func() {
if (this.head == null) {
return null;
}
ListNode fast = this.head;
ListNode slow = this.head;
while (fast != null && fast.next != null) {
fast = fast.next.next;
slow = slow.next;
if (fast == slow) {
break;
}
}
if (fast == null || fast.next == null) {
return null;
}
fast = this.head;
while (fast != slow) {
fast = fast.next;
slow = slow.next;
}
return fast;
}
//博哥写
public ListNode detectCycle() {
if (this.head == null) {
return null;
}
ListNode fast = this.head;
ListNode slow = this.head;
while (fast != null && fast.next != null) {
fast = fast.next.next;
slow = slow.next;
if (fast == slow) {
break;
}
}
if (fast == null || fast.next == null) {
return null;
}
fast = this.head;
while (fast != slow) {
fast = fast.next;
slow = slow.next;
}
return slow;
}
}
class ListNode {
public int val;
public ListNode next;//存节点地址
public ListNode(int val) {
this.val = val;
}
}