day4: 24题的递归写法不太会做,环形链表没来得及做,等明天
24.代码随想录
这个题不画图非常不容易做,图源 .代码随想录
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public ListNode swapPairs(ListNode head) {
// ListNode dummy = new ListNode(-1,head);
// ListNode cur = dummy;
// while(cur.next != null && cur.next.next != null){
// ListNode firstnode = cur.next;
// ListNode secondtnode = cur.next.next;
// ListNode thridnode = cur.next.next.next;
// cur.next = secondtnode;
// secondtnode.next = firstnode;
// firstnode.next = thridnode;
// cur = cur.next.next;
// }
// return dummy.next;
//判断,当偶数时,head为null;当奇数时,head.next为null
if(head == null || head.next == null){
return head;
}
ListNode secondNode = head.next;
//对下一组,也就是head.next.next进行递归;
ListNode newNode = swapPairs(secondNode.next);
//交换
secondNode.next = head;
head.next = newNode;
//因为要返回的是更新以后的头节点,所以返回的是next
return next;
}
}
19代码随想录
这道题我用常规的解法,步骤为:
1.通过遍历求出链表的size
2.size-n求出要删除的结点前一个的结点位置
3.删除
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public ListNode removeNthFromEnd(ListNode head, int n) {
//第一种解法 现遍历获得size
int size = 0;
ListNode cur = head;
while(cur != null){
size ++;
cur = cur.next;
}
if(size == 0){
return head;
}
int count = size - n;
ListNode cur1 = new ListNode(-1,head);
ListNode dummy = cur1;
while(count>0){
cur1 = cur1.next;
count--;
}
cur1.next = cur1.next.next;
return dummy.next;
}
}
双指针方法:一次遍历实现——快慢指针
class Solution {
public ListNode removeNthFromEnd(ListNode head, int n) {
ListNode fastNode = new ListNode(-1,head);
ListNode dummy = fastNode;
ListNode slowNode = fastNode;
//为什么是≥0呢?因为要找到要删除的元素的前一个元素,所以应该
是fast指针往前走n+1步
while(n>=0){
fastNode = fastNode.next;
n--;
}
while(fastNode!= null){
fastNode = fastNode.next;
slowNode = slowNode.next;
}
slowNode.next = slowNode.next.next;
return dummy.next;
}
}
面试题02.07代码随想录
这个题我是真没搞清楚,因为图里给我一些误解,后来才明白交点不是数值相等,而是指针相等。
搞清楚以后我用了遍历的方法,注意其中有一个小坑。就是每当重新遍历headB时,headB都应该时从头遍历的,所以需要提前记录headB,在headA每轮遍历时,恢复headB。但是时间复杂度很高。
/**
* 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 b = headB;
while(headA != null){
headB = b;
while(headB != null){
if(headB == headA){
return headB;
}else{
headB = headB.next;
}
}
headA = headA.next;
}
return null;
}
}
用双指针的方法更便捷,见 面试题02.07代码随想录
/**
* 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 a = headA;
ListNode b = headB;
int lenA = 0;
int lenB = 0;
while(a != null){
a = a.next;
lenA++;
}
while(b != null){
b = b.next;
lenB++;
}
a = headA;
b = headB;
if (lenB > lenA) {
//1. swap (lenA, lenB);
int tmpLen = lenA;
lenA = lenB;
lenB = tmpLen;
//2. swap (curA, curB);
ListNode tmpNode = a;
a = b;
b = tmpNode;
}
int gap = lenA - lenB;
while(gap>0){
a = a.next;
gap--;
}
while(a!=null){
if(a == b){
return a;
}
else{
a = a.next;
b = b.next;
}
}
return null;
}
}