1.删除链表中等于给定值 val 的所有节点
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode removeElements(ListNode head, int val) {
ListNode temp = new ListNode(0);
temp.next = head;
ListNode prev = temp;
ListNode cur = prev.next;
//cur 指向 prev 的后一个位置
while (cur != null) {
if (cur.val == val) {
prev.next = cur.next;
cur = cur.next;
} else {
prev = cur;
cur = cur.next;
}
}
return temp.next;
}
}
2.反转一个单链表
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode reverseList(ListNode head) {
ListNode pre = null;
ListNode cur = head;
while (cur != null) {
ListNode next = cur.next;
cur.next = pre;
pre = cur;
cur = next;
}
return pre;
}
}
3.给定一个带有头结点 head 的非空单链表,返回链表的中间结点。如果有两个中间结点,则返回第二个中间结点。
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode middleNode(ListNode head) {
if(head == null) {
return null;
}
if(head.next == null) {
return head;
}
int steps = getSize(head)/2;
ListNode cur = head;
for( int i = 0; i < steps; i++) {
cur = cur.next;
}
return cur;
}
private int getSize (ListNode head) {
int size = 0;
for(ListNode cur = head; cur != null; cur = cur.next) {
size++;
}
return size;
}
}
4.输入一个链表,输出该链表中倒数第k个结点。
/*
public class ListNode {
int val;
ListNode next = null;
ListNode(int val) {
this.val = val;
}
}*/
public class Solution {
public ListNode FindKthToTail(ListNode head,int k) {
if (head == null || k < 1) {
return null;
}
ListNode fast = head;
ListNode slow = head;
for (int i = 1; i < k; i++) {
if(fast.next != null) {
fast = fast.next;
} else {
return null;
}
}
while (fast.next != null){
fast = fast.next;
slow = slow.next;
}
return slow;
}
}
5.将两个有序链表合并为一个新的有序链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
ListNode prehead = new ListNode(-1);
ListNode prev = prehead;
while (l1 != null && l2 != null) {
if (l1.val <= l2.val) {
prev.next = l1;
l1 = l1.next;
}
else {
prev.next = l2;
l2 = l2.next;
}
prev = prev.next;
}
if (l1 == null) {
prev.next = l2;
}
if (l2 == null) {
prev.next = l1;
}
return prehead.next;
}
}
6.编写代码,以给定值x为基准将链表分割成两部分,所有小于x的结点排在大于或等于x的结点之前
import java.util.*;
/*
public class ListNode {
int val;
ListNode next = null;
ListNode(int val) {
this.val = val;
}
}*/
public class Partition {
public ListNode partition(ListNode pHead, int x) {
if (pHead == null || pHead.next == null) {
return pHead;
}
ListNode posMax = new ListNode(-1);
ListNode posMin = new ListNode(-1);
//设置两个头指针指向两个链表的首节点
ListNode maxHead = posMax;
ListNode minHead = posMin;
ListNode curNode = pHead;
while (curNode != null) {
if (curNode.val < x) {
posMin.next = curNode;
posMin = posMin.next;
} else {
posMax.next = curNode;
posMax = posMax.next;
}
curNode = curNode.next;
}
//posMin 链表的最后一个节点指向 posMax 链表的第一个节点
posMin.next = maxHead.next;
//posMax 链表的最后一个节点指向空指针
posMax.next = null;
return minHead.next;
}
}
7.在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针
/*
public class ListNode {
int val;
ListNode next = null;
ListNode(int val) {
this.val = val;
}
}
*/
public class Solution {
public ListNode deleteDuplication(ListNode pHead)
{
if (pHead == null || pHead.next == null) {
return pHead;
}
ListNode head = new ListNode(-1);
head.next = pHead;
ListNode pre = head;
ListNode last = head.next;
while (last != null) {
if (last.next != null && last.val == last.next.val) {
while (last.next != null && last.val == last.next.val) {
last = last.next;
}
pre.next = last.next;
last = last.next;
} else {
pre = pre.next;
last = last.next;
}
}
return head.next;
}
}
8.链表的回文结构
import java.util.*;
/*
public class ListNode {
int val;
ListNode next = null;
ListNode(int val) {
this.val = val;
}
}*/
public class PalindromeList {
public boolean chkPalindrome(ListNode A) {
// write code here
//先找到中间节点,然后把后面的链表逆置,和前面的链表比较
ListNode fast = A;
ListNode slow = A;
while (fast != null && fast.next != null) {
fast = fast.next.next;
slow = slow.next;
}
ListNode mid = slow.next;//中间节点的下一个节点
slow.next = null;//断连
ListNode cur = null;
ListNode prev = null;//标记逆置后的表头
//逆置
while (mid != null) {
prev = mid.next;
mid.next = cur;
cur = mid;
mid = prev;
}
//依次比较两个链表
while (A != null && cur != null) {
if (A.val != cur.val) {
return false;
}
A = A.next;
cur = cur.next;
}
return true;
}
}
9.输入两个链表,找出它们的第一个公共结点
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) {
* val = x;
* next = null;
* }
* }
*/
public class Solution {
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
if (headA == null || headB == null) {
return null;
}
ListNode pA = headA;
ListNode pB = headB;
while (pA != pB) {
pA = pA == null ? headB : pA.next;
pB = pB == null ? headA : pB.next;
}
return pA;
}
}
10.给定一个链表,判断链表中是否有环
/**
* Definition for singly-linked list.
* class ListNode {
* int val;
* ListNode next;
* ListNode(int x) {
* val = x;
* next = null;
* }
* }
*/
public class Solution {
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;
}
}
11.给定一个链表,返回链表开始入环的第一个节点。 如果链表无环,则返回 null
/**
* Definition for singly-linked list.
* class ListNode {
* int val;
* ListNode next;
* ListNode(int x) {
* val = x;
* next = null;
* }
* }
*/
public class Solution {
public ListNode detectCycle(ListNode head) {
ListNode slow = head;
ListNode fast = head;
while (true) {
if (fast == null || fast.next == null) {
return null;
}
slow = slow.next;
fast = fast.next.next;
if (fast == slow) {
break;
}
}
fast = head;
while (slow != fast) {
slow = slow.next;
fast = fast.next;
}
return fast;
}
}
链表问题还是比较复杂,难以理解,需要借助画图才可以有思路,得多练,多敲!