LeetCode19 删除链表的倒数第n个结点,中等难度
这道题可以利用双指针来解决
先让fast指针走n步,然后两个指针一起走,当fast指针走到链表尾部时,slow正好是要删除的前一个结点。
注意这里的判断条件是fast.next,如果不是这个,想是fsat,则需要先加一个虚结点。
class Solution {
public ListNode removeNthFromEnd(ListNode head, int n) {
ListNode fast = head;
ListNode slow = head;
//fast先走n步
for(int i = 0;i < n;i++){
fast = fast.next;
}
if(fast == null){
return head.next;
}
while(fast.next != null){
fast = fast.next;
slow = slow.next;
}
slow.next = slow.next.next;
return head;
}
}
当然这道题也可以用递归解决。
class Solution {
public ListNode removeNthFromEnd(ListNode head, int n) {
int num = Length(head,n);
//返回长度等于n,说明删除头结点
if(num == n){
return head.next;
}
return head;
}
int Length(ListNode node,int n){
if(node == null){
return 0;
}
int num = Length(node.next,n) + 1;
//当是n+1时,说明是要删除的结点的前一个结点
if(num == n + 1){
node.next = node.next.next;
}
return num;
}
}
LeetCode876 链表的中间结点,简单
这道题可以用快慢指针解决
每次right走两步,left走一步。
当right走到链表尾部时,left正好在链表的中间。
class Solution {
public ListNode middleNode(ListNode head) {
if(head == null)
return null;
ListNode left = head;
ListNode right = head;
while(right != null && right.next != null){
left = left.next;
right = right.next.next;
}
return left;
}
}
LeetCode61 旋转链表,中等
这道题也可以用快慢指针解决。
class Solution {
public ListNode rotateRight(ListNode head, int k) {
int len = getLength(head);
ListNode fast = head;
ListNode slow = head;
if(head == null || k == 0)
return head;
if(k % len == 0)
return head;
while((k % len) > 0){
fast = fast.next;
k--;
}
while(fast.next != null){
fast = fast.next;
slow = slow.next;
}
ListNode result = slow.next;
slow.next = null;
fast.next = head;
return result;
}
int getLength(ListNode head){
int len = 0;
ListNode node = head;
while(node != null){
len++;
node = node.next;
}
return len;
}
}
剑指offer52 两个链表的第一个公共子结点,简单
计算出两个链表长度的差值,
长的先走差值的长度,之后两个链表再一起遍历
class Solution {
ListNode getIntersectionNode(ListNode headA, ListNode headB) {
if(headA == null || headB == null)
return null;
int l1 = getLength(headA);
int l2 = getLength(headB);
int length = (l1 > l2) ? l1 - l2 : l2 - l1;
if(l1 >= l2){
for(int i = 0;i < length;i++)
headA = headA.next;
}else{
for(int i = 0;i < length;i++)
headB = headB.next;
}
while(headA != headB){
headA = headA.next;
headB = headB.next;
}
return headA;
}
int getLength(ListNode head){
ListNode cur = head;
int len = 0;
while(cur != null){
cur = cur.next;
len++;
}
return len;
}
}
我认为拼接两个链表更好一些
class Solution {
ListNode getIntersectionNode(ListNode headA, ListNode headB) {
if(headA == null || headB == null)
return null;
ListNode node1 = headA;
ListNode node2 = headB;
while(node1 != node2){
node1 = node1.next;
node2 = node2.next;
if(node1 != node2){
if(node1 == null)
node1 = headB;
if(node2 == null)
node2 = headA;
}
}
return node1;
}
}
LeetCode234 回文链表,简单
先反转,再遍历判断
class Solution {
public boolean isPalindrome(ListNode head) {
ListNode r1 = endOfFirst(head);
ListNode r2 = reverseList(r1.next);
if(head == null)
return true;
while(r2 != null){
if(head.val != r2.val){
return false;
}
head = head.next;
r2 = r2.next;
}
r1.next = reverseList(r2);
return true;
}
ListNode endOfFirst(ListNode head){
ListNode slow = head;
ListNode fast = head;
while(fast.next != null && fast.next.next != null){
fast = fast.next.next;
slow = slow.next;
}
return slow;
}
ListNode reverseList(ListNode node){
ListNode pre = null;
ListNode cur = node;
while(cur != null){
ListNode t = cur.next;
cur.next = pre;
pre = cur;
cur = t;
}
return pre;
}
}