链表
题目描述:给你一个链表,两两交换其中相邻的节点,并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题(即,只能进行节点交换)。
题目链接:[24. 两两交换链表中的节点(https://leetcode.cn/problems/swap-nodes-in-pairs/)
思路:
开始时,没有思路!
- 递归:一层一层递归下去,然后判断是否结束判断;
- 迭代:交换一组,进行下一组。
总结:
//递归
class Solution {
public ListNode swapPairs(ListNode head) {
if (head == null || head.next == null) {
return head;
}
ListNode newHead = head.next;
head.next = swapPairs(newHead.next);
newHead.next = head;
return newHead;
}
}
/**
// 迭代
* 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 dummyHead = new ListNode(0); // 哑节点
dummyHead.next = head;
ListNode temp = dummyHead;
while(temp.next != null && temp.next.next != null){ // 实现交换
ListNode node1 = temp.next;
ListNode node2 = temp.next.next;
temp.next = node2;
node1.next = node2.next;
node2.next = node1;
temp = node1;
}
return dummyHead.next;
}
}
- 删除链表的倒数第 N 个结点
题目描述:给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点。
题目链接:19. 删除链表的倒数第 N 个结点
思路:
- 双指针,第一个先前进n,然后两个指针一起前进,到最后第一个指针指向null,第二个指针的位置即为需要删除的。
总结:;
// 双指针解决问题
/**
* 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) {
ListNode dummy = new ListNode(0,head);
ListNode first = head;
ListNode second = dummy;
for(int i = 0; i < n; ++i){
first = first.next;
}
while(first != null){
first = first.next;
second = second.next;
}
second.next = second.next.next;
ListNode res = dummy;
return dummy.next;
}
}
面试题 02.07. 链表相交
题目描述:给你两个单链表的头节点 headA 和 headB ,请你找出并返回两个单链表相交的起始节点。如果两个链表没有交点,返回 null 。
图示两个链表在节点 c1 开始相交:
题目链接:面试题 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) {
Set<ListNode> visited = new HashSet<ListNode>();
ListNode temp = headA;
while(temp != null){
visited.add(temp);
temp = temp.next;
}
temp = headB;
while(temp != null){
if(visited.contains(temp)){
return temp;
}
temp = temp.next;
}
return null;
}
}
//双指针方法,难想到
public class Solution {
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
if(headA == null || headB == null){
return null;
}
ListNode pA = headA, pB = headB;
while(pA != pB){
pA = pA == null ? headB : pA.next;
pB = pB == null ? headA : pB.next;
}
return pB;
}
}