class Solution {
Map<Node, Node> cachedNode = new HashMap<Node, Node>();
public Node copyRandomList(Node head) {
if (head == null) {
return null;
}
if (!cachedNode.containsKey(head)) {
Node headNew = new Node(head.val);
cachedNode.put(head, headNew);
headNew.next = copyRandomList(head.next);
headNew.random = copyRandomList(head.random);
}
return cachedNode.get(head);
}
}
class Solution {
public ListNode reverseBetween(ListNode head, int left, int right) {
// 因为头节点有可能发生变化,使用虚拟头节点可以避免复杂的分类讨论
ListNode dummyNode = new ListNode(-1);
dummyNode.next = head;
ListNode pre = dummyNode;
// 第 1 步:从虚拟头节点走 left - 1 步,来到 left 节点的前一个节点
// 建议写在 for 循环里,语义清晰
for (int i = 0; i < left - 1; i++) {
pre = pre.next;
}
// 第 2 步:从 pre 再走 right - left + 1 步,来到 right 节点
ListNode rightNode = pre;
for (int i = 0; i < right - left + 1; i++) {
rightNode = rightNode.next;
}
// 第 3 步:切断出一个子链表(截取链表)
ListNode leftNode = pre.next;
ListNode curr = rightNode.next;
// 注意:切断链接
pre.next = null;
rightNode.next = null;
// 第 4 步:同第 206 题,反转链表的子区间
reverseLinkedList(leftNode);
// 第 5 步:接回到原来的链表中
pre.next = rightNode;
leftNode.next = curr;
return dummyNode.next;
}
private void reverseLinkedList(ListNode head) {
// 也可以使用递归反转一个链表
ListNode pre = null;
ListNode cur = head;
while (cur != null) {
ListNode next = cur.next;
cur.next = pre;
pre = cur;
cur = next;
}
}
}
class Solution {
public ListNode reverseBetween(ListNode head, int left, int right) {
// 设置 dummyNode 是这一类问题的一般做法
ListNode dummyNode = new ListNode(-1);
dummyNode.next = head;
ListNode pre = dummyNode;
for (int i = 0; i < left - 1; i++) {
pre = pre.next;
}
ListNode cur = pre.next;
ListNode next;
for (int i = 0; i < right - left; i++) {
next = cur.next;
cur.next = next.next;
next.next = pre.next;
pre.next = next;
}
return dummyNode.next;
}
}
//迭代反转两个具体的节点
public ListNode[] myReverse(ListNode head, ListNode tail) {
ListNode prev = tail.next;
ListNode cur = head;
while (prev != tail) {
ListNode nex = cur.next;
cur.next = prev;
prev = cur;
cur = nex;
}
return new ListNode[]{tail, head};
}
ListNode successor = null; // 后驱节点
// 反转以 head 为起点的 n 个节点,返回新的头结点
ListNode reverseN(ListNode head, int n) {
if (n == 1) {
// 记录第 n + 1 个节点
successor = head.next;
return head;
}
// 以 head.next 为起点,需要反转前 n - 1 个节点
ListNode last = reverseN(head.next, n - 1);
head.next.next = head;
// 让反转之后的 head 节点和后面的节点连起来
head.next = successor;
return last;
}
ListNode reverseBetween(ListNode head, int m, int n) {
// base case
if (m == 1) {
return reverseN(head, n);
}
// 前进到反转的起点触发 base case---只到m=1
head.next = reverseBetween(head.next, m - 1, n - 1);
return head;
}
class Solution {
public static ListNode reverseKGroup(ListNode head, int k) {
ListNode dummy = new ListNode(-1, head), prev = dummy;
while (true) {
// 检查剩余节点是否有k个,不足则返回
ListNode last = prev;
for (int i = 0; i < k; i++) {
last = last.next;
if (last == null) {
return dummy.next;
}
}
// 翻转k个节点,穿针引线
ListNode curr = prev.next, next;
for (int i = 0; i < k - 1; i++) {
next = curr.next;
curr.next = next.next;
next.next = prev.next;
prev.next = next;
}
prev = curr;
}
}
}
class Solution {
public ListNode reverseKGroup(ListNode head, int k) {
ListNode curr=head;
int i=0;
while(curr !=null){
i++;
curr=curr.next;
}
for(int j=0; j< i/k; j++){
head= reverseBetween(head,j*k+1,j*k+k);
}
return head;
}
ListNode successer=null;
public ListNode reverse(ListNode head, int m){
if(m==1){
successer=head.next;
return head;
}
ListNode last=reverse(head.next, m-1);
head.next.next =head;
head.next=successer;
return last;
}
public ListNode reverseBetween(ListNode head, int m, int n){
if(m==1){
return reverse(head, n);
}
head.next = reverseBetween(head.next, m-1,n-1);
return head;
}
}
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 ans = dummy.next;
return ans;
}
}
class Solution {
public ListNode deleteDuplicates(ListNode head) {
ListNode dummyNode = new ListNode(-1);
dummyNode.next=head;
Set<Integer> set = new HashSet<Integer>();
ListNode pre=dummyNode;
ListNode curr=head;
while(pre.next!=null){
//先比较有没有重复,有重复就添加
if(pre.next.next!=null && pre.next.val ==pre.next.next.val){
set.add(pre.next.val);
}
//再判断删除
if(set.contains(pre.next.val)){
pre.next= pre.next.next;
}else{
pre=pre.next;
}
}
return dummyNode.next;
}
}
class Solution {
public ListNode rotateRight(ListNode head, int k) {
if (k == 0 || head == null || head.next == null) {
return head;
}
int n = 1;
ListNode iter = head;
while (iter.next != null) {
iter = iter.next;
n++;
}
int add = n - k % n;
if (add == n) {
return head;
}
iter.next = head;
while (add-- > 0) {
iter = iter.next;
}
ListNode ret = iter.next;
iter.next = null;
return ret;
}
}