Leetcode: 24
//使用虚拟头节点
class Solution {
public ListNode swapPairs(ListNode head) {
ListNode dummyNode = new ListNode(-1);
dummyNode.next = head;
ListNode cur = dummyNode;
ListNode temp; // 保存两个节点后面的节点
ListNode firstNode;
ListNode secondNode;
while(cur.next != null && cur.next.next != null){
temp = cur.next.next.next;
firstNode = cur.next;
secondNode = cur.next.next;
cur.next = secondNode;
secondNode.next = firstNode;
firstNode.next = temp;
cur = cur.next.next;
}
return dummyNode.next;
}
}
Leetcode: 19 删除列表倒数第N个节点
两遍翻转(自己写的)
class Solution {
public ListNode removeNthFromEnd(ListNode head, int n) {
ListNode tmp1 = reverseNode(head);
ListNode toDelete = tmp1;// tmp1应为实际开始节点
if(n == 1) return reverseNode(tmp1.next);
for(int i = 0; i < n - 2; i++){
toDelete = toDelete.next;
}
toDelete.next = toDelete.next.next;
return reverseNode(tmp1);
}
public ListNode reverseNode(ListNode head){
ListNode cur = head;
ListNode tmp1 = null;
ListNode tmp2;
while(cur != null){
tmp2 = cur.next;
cur.next = tmp1;
tmp1 = cur;
cur = tmp2;
}
return tmp1;
}
}
双指针(这才是好思路)
class Solution {
public ListNode removeNthFromEnd(ListNode head, int n) {
ListNode dummyNode = new ListNode(0);
dummyNode.next = head;
ListNode fastIndex = dummyNode;
ListNode slowIndex = dummyNode;
for (int i = 0; i < n ; i++){
fastIndex = fastIndex.next;
}
while (fastIndex.next != null){
fastIndex = fastIndex.next;
slowIndex = slowIndex.next;
}
slowIndex.next = slowIndex.next.next;
return dummyNode.next;
}
}
Leetode: 面试题02.07.链表相交
数值相同不代表指针相同; 其实类似双指针
public class Solution {
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
ListNode curA = headA;
ListNode curB = headB;
int lenA = 0, lenB = 0;
while(curA!=null){
lenA++;
curA = curA.next;
}
while(curB!=null){
lenB++;
curB = curB.next;
}
curA = headA;
curB = headB;
if(lenB > lenA){
int tmplen = lenA;
lenA = lenB;
lenB = tmplen;
ListNode tmpnode = curA;
curA = curB;
curB = tmpnode;
}
int gap = lenA - lenB;
while(gap-- > 0) curA = curA.next;
while (curA != null) {
if (curA == curB) {
return curA;
}
curA = curA.next;
curB = curB.next;
}
return null;
}
}
Leetcode: 142 环形列表
利用不同速的快慢指针是否相遇判断是否有环
数学推理很妙代码随想录 (programmercarl.com)
public class Solution {
public ListNode detectCycle(ListNode head) {
ListNode slow = head;
ListNode fast = head;
while (fast != null && fast.next != null) {
slow = slow.next;
fast = fast.next.next;
if (slow == fast) {// 有环
ListNode index1 = fast;
ListNode index2 = head;
// 两个指针,从头结点和相遇结点,各走一步,直到相遇,相遇点即为环入口
while (index1 != index2) {
index1 = index1.next;
index2 = index2.next;
}
return index1;
}
}
return null;
}
}
哈希表,自己写的
public class Solution {
public ListNode detectCycle(ListNode head) {
if(head==null) return null;
HashMap<ListNode, Integer> nodemap = new HashMap<ListNode, Integer>();
ListNode cur = head;
while(nodemap.getOrDefault(cur,0)==0){
nodemap.put(cur, 1);
cur = cur.next;
if(cur==null) return null;
}
return cur;
}
}
哈希表,复制的,耗时差不多
public class Solution {
public ListNode detectCycle(ListNode head) {
Set<ListNode> set = new HashSet<>();
ListNode curr = head;
while (curr != null) {
if (!set.add(curr)) return curr;
curr = curr.next;
}
return null;
}
}