目录
1.移除链表元素(203)
public ListNode removeElements(ListNode head, int val) {
while(head != null && head.val == val){
head = head.next;
}
for (ListNode pre = head; pre != null; pre = pre.next) {
while(pre.next != null && pre.next.val == val) {
pre.next = pre.next.next;
}
}
return head;
}
public ListNode removeElements(ListNode head, int val) {
//链表内没有元素,终止条件
if (head == null){
return null;
}
head.next = removeElements(head.next,val);
//删除操作
if (head.val == val){
return head.next;
}
return head;
}
2.删除排序链表中的重复元素(83)
public ListNode deleteDuplicates(ListNode head) {
//当链表为空或者只有一个元素的时候,不可能有重复的元素
if (head == null || head.next == null){
return head;
}
ListNode pre = head;
ListNode cur = pre.next;
while(cur != null){
if (pre.val != cur.val) {
pre = pre.next;
cur = cur.next;
} else {
pre.next = cur.next;
cur = cur.next;
}
}
return head;
}
public ListNode deleteDuplicates(ListNode head) {
if (head == null || head.next == null) {
return head;
}
head.next = deleteDuplicates(head.next);
if (head.val == head.next.val) {
return head.next;
}
return head;
}
3.删除排序链表中的重复元素 II(82)
public ListNode deleteDuplicates(ListNode head) {
ListNode dummyHead = new ListNode();
dummyHead.next = head;
ListNode pre = dummyHead;
ListNode cur = pre.next;
while(cur != null) {
ListNode next= cur.next;
if (next == null){
//链表内只有一个节点或者链表遍历完了
break;
} else {
//链表内至少有两个结点
//不相等,三指针同时向后移动,在下一次循环开始的时候,next会向后走一步
if (cur.val != next.val) {
pre = pre.next;
cur = cur.next;
} else {
//相等时,让next向后走到第一个不相等的元素
while(next != null && cur.val == next.val) {
next = next.next;
}
pre.next = next;
//cur向后走一步
cur = next;
}
}
}
//返回头结点
return dummyHead.next;
}
图解:
public ListNode deleteDuplicates(ListNode head) {
if (head == null || head.next == null){
return head;
}
if (head.val != head.next.val) {
head.next = deleteDuplicates(head.next);
return head;
} else {
//删头结点
ListNode nextHead = head.next;
while (nextHead != null && head.val == nextHead.val){
nextHead = nextHead.next;
}
return deleteDuplicates(nextHead);
}
}
4.反转链表(206)
public ListNode reverseList(ListNode head) {
ListNode dummyHead = new ListNode();
while(head != null) {
ListNode node = new ListNode(head.val);
node.next = dummyHead.next;
dummyHead.next = node;
head = head.next;
}
return dummyHead.next;
}
public ListNode reverseList(ListNode head) {
if(head == null || head.next == null) {
return head;
}
ListNode pre = null;
ListNode cur = head;
while (cur != null) {
ListNode next = cur.next;
cur.next = pre;
pre = cur;
cur = next;
}
return pre;
}
public ListNode reverseList(ListNode head) {
if (head == null || head.next == null){
return head;
}
ListNode node = head.next;
ListNode newHead = reverseList(head.next);
node.next = head;
//不能省略,会成环
head.next = null;
return newHead;
}
图示:
5.链表的中间结点(876)
public ListNode middleNode(ListNode head) {
int count = 0;
for(ListNode x = head; x != null; x = x.next) {
count ++;
}
ListNode x = head;
for (int i = 0; i < count / 2; i++) {
x = x.next;
}
return x;
}
方法二:快慢指针(双引用)
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;
}
推导:
6.链表中倒数第k个节点(剑指 Offer 22)
public ListNode getKthFromEnd(ListNode head, int k) {
int count = 0;
for (ListNode x = head; x != null; x = x.next) {
count ++;
}
ListNode node = head;
for (int i = 0; i < count - k; i++) {
node = node.next;
}
return node;
}
public ListNode getKthFromEnd(ListNode head, int k) {
ListNode fast = head;
for (int i = 0; i < k ; i++) {
fast = fast.next;
}
ListNode slow = head;
while(fast != null){
fast = fast.next;
slow = slow.next;
}
return slow;
}
7.回文链表
public ListNode reverseList(ListNode head) {
ListNode dummyHead = new ListNode();
while(head != null) {
ListNode node = new ListNode(head.val);
node.next = dummyHead.next;
dummyHead.next = node;
head = head.next;
}
return dummyHead.next;
}
public boolean isPalindrome(ListNode head) {
ListNode newLink = reverseList(head);
while(head != null) {
if (head.val != newLink.val) {
return false;
}
head = head.next;
newLink = newLink.next;
}
return true;
}
public ListNode reverse(ListNode head){
if (head == null || head.next == null){
return head;
}
ListNode node = head.next;
ListNode newHead = reverse(head.next);
node.next = head;
head.next = null;
return newHead;
}
//找中间结点
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;
}
public boolean isPalindrome(ListNode head) {
ListNode midNode = middleNode(head);
ListNode resHead = reverse(midNode);
while(resHead != null){
if (head.val != resHead.val){
return false;
}
resHead = resHead.next;
head = head.next;
}
return true;
}
8.合并两个有序链表(21)
public ListNode mergeTwoLists(ListNode list1, ListNode list2) {
if (list1 == null){
return list2;
}
if (list2 == null){
return list1;
}
ListNode dummyHead = new ListNode();
//新链表的尾结点
ListNode tail = dummyHead;
while(list1 != null && list2 != null) {
if(list1.val <= list2.val) {
tail.next = list1;
tail = list1;
list1 = list1.next;
} else {
tail.next = list2;
tail = list2;
list2 = list2.next;
}
}
if (list1 == null){
tail.next = list2;
}
if (list2 == null){
tail.next = list1;
}
return dummyHead.next;
}
public ListNode mergeTwoLists(ListNode list1, ListNode list2) {
if (list1 == null){
return list2;
}
if (list2 == null){
return list1;
}
if (list1.val <= list2.val){
list1.next = mergeTwoLists(list1.next,list2);
return list1;
}else {
list2.next = mergeTwoLists(list2.next,list1);
return list2;
}
9.分割链表(02.04)
public ListNode partition(ListNode head, int x) {
if (head == null || head.next == null){
return head;
}
ListNode smallHead = new ListNode();
ListNode smallTail = smallHead;
ListNode bigHead = new ListNode();
ListNode bigTail = bigHead;
while (head != null) {
if (head.val < x) {
smallTail.next = head;
smallTail = head;
} else {
bigTail.next = head;
bigTail = head;
}
head = head.next;
}
bigTail.next = null;
smallTail.next = bigHead.next;
return smallHead.next;
}
10.相交链表(160)
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
ListNode l1 = headA;
ListNode l2 = headB;
while (l1 != l2) {
l1 = l1 == null ? headB : l1.next;
l2 = l2 == null ? headA : l2.next;
}
return l1;
}
图解:
11.环形链表(141)
public boolean hasCycle(ListNode head) {
ListNode fast = head,slow = head;
while(fast != null && fast.next != null){
fast = fast.next.next;
slow = slow.next;
//追上了
if (fast == slow){
return true;
}
}
//直线
return false;
}
12.反转链表 II(92)
public ListNode reverseBetween(ListNode head, int left, int right) {
ListNode dummyHead = new ListNode();
dummyHead.next = head;
//pre指向待反转区间的前驱节点
ListNode pre = dummyHead;
//cur指向待反转区间的第一个节点
ListNode cur = pre.next;
//让pre和cur走left - 1步,走到对应位置
for (int i = 0; i < left - 1; i++) {
pre = pre.next;
cur = cur.next;
}
//只需要反转right - left次就可以
for (int i = 0; i < right - left; i++) {
//暂存下一个要处理的结点
ListNode next = cur.next;
//先删除next,在头插到pre的后面
cur.next = next.next;
//头插
next.next = pre.next;
pre.next = next;
}
return dummyHead.next;
}