链表题目列表
* 单链表实现 增 删 查 改
* 1.头结点不能动,所以需要辅助指针
* 我理解的误区是,整个temp.next改变的是temp,head没有变。实际应该temp只是一个指针
* 指向这根链表的某一个位置,修改的还是链表
*
* 链表类题目主要有以下几种题型:
* 删除链表节点
* 反转链表
* 合并链表
* 排序链表
* 环形链表
1 删除链表节点
package demo01.ListNode;
import java.util.HashSet;
public class deleteListNode {
public ListNode removeElements(ListNode head, int val) {
if(head==null) return head;
ListNode dummy = new ListNode(val-1,head);
ListNode cur = dummy;
while(cur.next!=null){
if(cur.next.val == val) cur.next = cur.next.next;
else cur = cur.next;
}
return dummy.next;
}
public ListNode removeElements2(ListNode head, int val) {
if(head==null) return head;
head.next = removeElements2(head.next,val);
if(head.val==val) return head.next;
else return head;
}
public ListNode removeDuplicateNodes(ListNode head) {
if(head==null) return head;
HashSet<Integer> set = new HashSet<>();
ListNode cur = head;
set.add(cur.val);
while(cur.next!=null){
if(!set.add(cur.next.val)) cur.next = cur.next.next;
else cur = cur.next;
}
return head;
}
public ListNode deleteDuplicates(ListNode head) {
if(head==null) return head;
ListNode dummy = new ListNode(head.val-1,head);
ListNode fast = dummy.next;
ListNode slow = dummy;
while(fast!=null && fast.next!=null){
if(fast.val==fast.next.val){
while(fast.next != null && fast.val == fast.next.val){
fast = fast.next;
}
slow.next = fast.next;
fast = fast.next;
}else{
slow = slow.next;
fast = fast.next;
}
}
return dummy.next;
}
public ListNode removeNthFromEnd(ListNode head, int n) {
if(head==null) return head;
ListNode dummy = new ListNode(0,head);
ListNode fast = dummy.next;
ListNode slow = dummy;
for (int i = 0; i < n; i++) {
fast = fast.next;
}
while(fast!=null){
slow = slow.next;
fast = fast.next;
}
slow.next = slow.next.next;
return dummy.next;
}
public ListNode middleNode(ListNode head) {
if(head==null) return head;
ListNode pre = head;
ListNode cur = head;
while(cur!=null && cur.next!=null){
pre = pre.next;
cur = cur.next.next;
}
return pre;
}
public ListNode partition(ListNode head, int x) {
if(head==null) return head;
ListNode smallHead = new ListNode(0);
ListNode small = smallHead;
ListNode largeHead = new ListNode(0);
ListNode large = largeHead;
while(head!=null){
if(head.val<x){
small.next = head;
small = small.next;
}else{
large.next = head;
large = large.next;
}
head = head.next;
}
small.next = largeHead.next;
large.next = null;
return smallHead.next;
}
public ListNode oddEvenList(ListNode head) {
if(head==null) return head;
ListNode odd = head;
ListNode even = head.next;
ListNode evenHead = even;
while(even!=null && even.next!=null){
odd.next = even.next;
odd = odd.next;
even.next = odd.next;
even = even.next;
}
odd.next = evenHead;
return head;
}
}
2 反转链表
public class all {
public ListNode reverseList(ListNode head) {
if(head==null) return head;
ListNode pre = null;
ListNode cur = head;
while(cur!=null){
ListNode temp = cur.next;
cur.next = pre;
pre = cur;
cur = temp;
}
return pre;
}
public ListNode reverseList2(ListNode head) {
if(head==null) return head;
ListNode last = reverseList2(head.next);
head.next.next = head;
head.next = null;
return last;
}
public ListNode reverseBetween(ListNode head, int left, int right) {
if(head==null) return head;
ListNode dummy = new ListNode(0,head);
ListNode pre = dummy;
for (int i = 0; i < left-1; i++) {
pre = pre.next;
}
ListNode cur = pre.next;
for (int i = 0; i < right-left; i++) {
ListNode temp = cur.next;
cur.next = temp.next;
temp.next = pre.next;
pre.next = temp;
}
return dummy.next;
}
public ListNode reverseKGroup(ListNode head, int k) {
if(head==null) return head;
ListNode cur = head;
for (int i = 0; i < k; i++) {
if(cur==null) return head;
cur = cur.next;
}
ListNode newHead = reverse(head, cur);
head.next = reverseKGroup(cur, k);
return newHead;
}
public ListNode reverse(ListNode begin,ListNode end){
ListNode pre = null;
ListNode cur = begin;
while(cur!=end){
ListNode temp = cur.next;
cur.next = pre;
pre = cur;
cur = temp;
}
return pre;
}
public boolean isPalindrome(ListNode head) {
if(head==null) return true;
ListNode pre = head;
ListNode cur = head;
while(cur!=null && cur.next!=null){
pre = pre.next;
cur = cur.next.next;
}
if(cur!=null) pre = pre.next;
ListNode right = reverseList(pre);
ListNode left = head;
while(right!=null){
if(left.val!=right.val) return false;
left = left.next;
right = right.next;
}
return true;
}
}
3 环形链表
* 【环形链表】
* 160、相交链表,给你两个单链表的头节点 headA 和 headB ,找出并返回两个单链表相交的起始节点。如果两个链表没有交点,返回 null
* 141、环形链表
* 142、环形链表 II
* @author sommer1111
* @date 2021/5/31 10:04
public class all {
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
if (headA == null || headB == null) return null;
ListNode node1 = headA;
ListNode node2 = headB;
while (node1 != node2) {
node1 = node1 == null ? headB : node1.next;
node2 = node2 == null ? headA : node2.next;
}
return node1;
}
public boolean hasCycle(ListNode head) {
if(head==null || head.next==null) return false;
ListNode slow = head;
ListNode fast = head.next;
while(slow!=fast){
if(fast==null || fast.next==null) return false;
slow = slow.next;
fast = fast.next.next;
}
return true;
}
public ListNode detectCycle(ListNode head) {
if (head == null || head.next == null) return null;
ListNode slow = head;
ListNode fast = head;
while (fast != null && fast.next != null) {
slow = slow.next;
fast = fast.next.next;
if (fast == slow) {
ListNode cur = head;
while (cur != slow) {
cur = cur.next;
slow = slow.next;
}
return slow;
}
}
return null;
}
}
4 合并链表
package _03_ListNode;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
* 合并链表
* 21、合并两个有序链表
* 23、合并 k 个有序链表,将 k 个有序的链表合并
*
* @author sommer1111
* @date 2021/5/31 10:04
*/
public class all {
public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
if(l1==null || l2==null) return l1==null?l2:l1;
ListNode newHead = new ListNode(0);
ListNode cur = newHead;
while(l1!=null && l2!=null){
if(l1.val<l2.val){
cur.next = l1;
l1 = l1.next;
}else{
cur.next = l2;
l2 = l2.next;
}
cur = cur.next;
}
cur.next=l1==null?l2:l1;
return newHead.next;
}
public ListNode mergeTwoLists2(ListNode l1, ListNode l2) {
if(l1==null) return l2;
if(l2==null) return l1;
if(l1.val<l2.val){
l1.next = mergeTwoLists2(l1.next,l2);
return l1;
}else{
l2.next = mergeTwoLists2(l1,l2.next);
return l2;
}
}
public ListNode mergeKLists(ListNode[] lists) {
return mergeFrom(lists,0,lists.length-1);
}
public ListNode mergeFrom(ListNode[] lists,int left,int right) {
if(left==right) return lists[left];
if(left<right){
int mid = left + (right-left)/2;
return mergeTwoLists2(
mergeFrom(lists,left,mid),
mergeFrom(lists,mid+1,right));
}
return null;
}
}
5 排序链表
还有两题,写不下去了,先放着。。。。
* 排序链表
* 147、对链表进行插入排序
* 148、排序链表
|