3.17 链表
This commit is contained in:
parent
5218596c0a
commit
b9c0de8d1b
36
src/main/java/linkedlist/AddTwoNumbers.java
Normal file
36
src/main/java/linkedlist/AddTwoNumbers.java
Normal file
@ -0,0 +1,36 @@
|
||||
package linkedlist;
|
||||
/**
|
||||
* 题目: 2. 两数相加 (mergeTwoLists)
|
||||
* 描述:给你两个 非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。
|
||||
* 请你将两个数相加,并以相同形式返回一个表示和的链表。
|
||||
* 你可以假设除了数字 0 之外,这两个数都不会以 0 开头。
|
||||
|
||||
* 链接:https://leetcode.cn/problems/add-two-numbers/
|
||||
|
||||
*/
|
||||
public class AddTwoNumbers {
|
||||
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
|
||||
ListNode dummy = new ListNode(-1);
|
||||
ListNode current = dummy;
|
||||
int carry = 0;
|
||||
|
||||
while(l1 != null || l2 != null) {
|
||||
int x = (l1 != null) ? l1.val : 0;
|
||||
int y = (l2 != null) ? l2.val : 0;
|
||||
int sum = x + y + carry;
|
||||
|
||||
current.next = new ListNode(sum % 10);
|
||||
current = current.next;
|
||||
carry = sum / 10;
|
||||
|
||||
if(l1 != null) l1 = l1.next;
|
||||
if(l2 != null) l2 = l2.next;
|
||||
}
|
||||
|
||||
if(carry > 0) {
|
||||
current.next = new ListNode(carry);
|
||||
}
|
||||
|
||||
return dummy.next;
|
||||
}
|
||||
}
|
46
src/main/java/linkedlist/CopyRandomList.java
Normal file
46
src/main/java/linkedlist/CopyRandomList.java
Normal file
@ -0,0 +1,46 @@
|
||||
package linkedlist;
|
||||
import java.util.HashMap;
|
||||
|
||||
/**
|
||||
* 题目: 138. 随机链表的复制 (copyRandomList)
|
||||
* 描述:给你一个长度为 n 的链表,每个节点包含一个额外增加的随机指针 random ,该指针可以指向链表中的任何节点或空节点。
|
||||
*
|
||||
* 构造这个链表的 深拷贝。 深拷贝应该正好由 n 个 全新 节点组成,其中每个新节点的值都设为其对应的原节点的值。新节点的 next 指针和 random 指针也都应指向复制链表中的新节点,并使原链表和复制链表中的这些指针能够表示相同的链表状态。复制链表中的指针都不应指向原链表中的节点 。
|
||||
*
|
||||
* 例如,如果原链表中有 X 和 Y 两个节点,其中 X.random --> Y 。那么在复制链表中对应的两个节点 x 和 y ,同样有 x.random --> y 。
|
||||
*
|
||||
* 返回复制链表的头节点。
|
||||
*
|
||||
* 用一个由 n 个节点组成的链表来表示输入/输出中的链表。每个节点用一个 [val, random_index] 表示:
|
||||
*
|
||||
* val:一个表示 Node.val 的整数。
|
||||
* random_index:随机指针指向的节点索引(范围从 0 到 n-1);如果不指向任何节点,则为 null 。
|
||||
* 你的代码 只 接受原链表的头节点 head 作为传入参数。
|
||||
|
||||
|
||||
* 链接:https://leetcode.cn/problems/copy-list-with-random-pointer/
|
||||
|
||||
*/
|
||||
//不会做 需要重做
|
||||
public class CopyRandomList {
|
||||
public Node copyRandomList(Node head) {
|
||||
if (head == null)
|
||||
return null;
|
||||
HashMap<Node, Node> map = new HashMap<>(); // 原节点 -> 新节点映射
|
||||
Node curr = head;
|
||||
// 第一次遍历:创建新节点并建立映射
|
||||
while (curr != null) {
|
||||
map.put(curr, new Node(curr.val));
|
||||
curr = curr.next;
|
||||
}
|
||||
// 第二次遍历:设置next和random指针
|
||||
curr = head;
|
||||
while (curr != null) {
|
||||
Node clone = map.get(curr);
|
||||
clone.next = map.get(curr.next);
|
||||
clone.random = map.get(curr.random);
|
||||
curr = curr.next;
|
||||
}
|
||||
return map.get(head);
|
||||
}
|
||||
}
|
53
src/main/java/linkedlist/DetectCycle.java
Normal file
53
src/main/java/linkedlist/DetectCycle.java
Normal file
@ -0,0 +1,53 @@
|
||||
package linkedlist;
|
||||
|
||||
import java.util.HashSet;
|
||||
|
||||
/**
|
||||
* 题目: 142. 环形链表 II (detectCycle)
|
||||
* 描述:给定一个链表的头节点 head ,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。
|
||||
* 如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。如果 pos 是 -1,则在该链表中没有环。注意:pos 不作为参数进行传递,仅仅是为了标识链表的实际情况。
|
||||
* 不允许修改 链表。
|
||||
|
||||
* 链接:https://leetcode.cn/problems/linked-list-cycle-ii/
|
||||
|
||||
*/
|
||||
public class DetectCycle {
|
||||
//哈希
|
||||
public ListNode detectCycle1(ListNode head) {
|
||||
ListNode pos = head;
|
||||
HashSet<ListNode> visited = new HashSet<ListNode>();
|
||||
while (pos != null) {
|
||||
if (visited.contains(pos)) {
|
||||
return pos;
|
||||
} else {
|
||||
visited.add(pos);
|
||||
}
|
||||
pos = pos.next;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
//Floyd 快慢指针
|
||||
public ListNode detectCycle(ListNode head) {
|
||||
if (head == null) {
|
||||
return null;
|
||||
}
|
||||
ListNode slow = head, fast = head;
|
||||
while (fast != null) {
|
||||
slow = slow.next;
|
||||
if (fast.next != null) {
|
||||
fast = fast.next.next;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
if (fast == slow) {
|
||||
ListNode ptr = head;
|
||||
while (ptr != slow) {
|
||||
ptr = ptr.next;
|
||||
slow = slow.next;
|
||||
}
|
||||
return ptr;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
76
src/main/java/linkedlist/HasCycle.java
Normal file
76
src/main/java/linkedlist/HasCycle.java
Normal file
@ -0,0 +1,76 @@
|
||||
package linkedlist;
|
||||
|
||||
import java.util.HashSet;
|
||||
|
||||
/**
|
||||
* 题目: 141. 环形链表 (hasCycle)
|
||||
* 描述:给你一个链表的头节点 head ,判断链表中是否有环。
|
||||
* 如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。注意:pos 不作为参数进行传递 。仅仅是为了标识链表的实际情况。
|
||||
* 如果链表中存在环 ,则返回 true 。 否则,返回 false 。
|
||||
|
||||
* 链接:https://leetcode.cn/problems/linked-list-cycle/
|
||||
输入:head = [3,2,0,-4], pos = 1
|
||||
输出:true
|
||||
解释:链表中有一个环,其尾部连接到第二个节点。
|
||||
*/
|
||||
public class HasCycle {
|
||||
//哈希法
|
||||
public boolean hasCycle1(ListNode head) {
|
||||
HashSet<ListNode>set=new HashSet<>();
|
||||
ListNode temp=head;
|
||||
while (temp!=null) {
|
||||
if (!set.contains(temp))
|
||||
set.add(temp);
|
||||
else
|
||||
return true;
|
||||
temp = temp.next;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
//翻转指针
|
||||
public boolean hasCycle2(ListNode head) {
|
||||
// 如果链表为空或者只有一个节点,直接返回无环
|
||||
if (head == null || head.next == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// 用 originalHead 保存最初的头节点
|
||||
ListNode originalHead = head;
|
||||
// 从 head.next 开始遍历,先把 head 与链表分离
|
||||
ListNode cur = head.next;
|
||||
ListNode pre = head;
|
||||
// 断开 head 和后面的连接
|
||||
head.next = null;
|
||||
|
||||
while (cur != null) {
|
||||
// 如果当前节点又指回了 originalHead,则说明出现环
|
||||
if (cur == originalHead) {
|
||||
return true;
|
||||
}
|
||||
// 反转指针
|
||||
ListNode temp = cur.next;
|
||||
cur.next = pre;
|
||||
// 移动 pre 和 cur
|
||||
pre = cur;
|
||||
cur = temp;
|
||||
}
|
||||
|
||||
// 走到空指针,说明无环
|
||||
return false;
|
||||
}
|
||||
public boolean hasCycle(ListNode head) {
|
||||
if (head == null || head.next == null) {
|
||||
return false;
|
||||
}
|
||||
ListNode slow = head;
|
||||
ListNode fast = head.next;
|
||||
while (slow != fast) {
|
||||
if (fast == null || fast.next == null) {
|
||||
return false;
|
||||
}
|
||||
slow = slow.next;
|
||||
fast = fast.next.next;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
@ -7,4 +7,5 @@ public class ListNode {
|
||||
val = x;
|
||||
next = null;
|
||||
}
|
||||
ListNode(int val, ListNode next) { this.val = val; this.next = next; }
|
||||
}
|
||||
|
38
src/main/java/linkedlist/MergeTwoLists.java
Normal file
38
src/main/java/linkedlist/MergeTwoLists.java
Normal file
@ -0,0 +1,38 @@
|
||||
package linkedlist;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 题目: 21. 合并两个有序链表 (mergeTwoLists)
|
||||
* 描述:将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。
|
||||
|
||||
* 链接:https://leetcode.cn/problems/merge-two-sorted-lists/
|
||||
|
||||
*/
|
||||
public class MergeTwoLists {
|
||||
public ListNode mergeTwoLists(ListNode list1, ListNode list2) {
|
||||
ListNode head = new ListNode(-1);
|
||||
ListNode mv = head;
|
||||
ListNode mv1 = list1;
|
||||
ListNode mv2 = list2;
|
||||
while(mv1 != null && mv2 !=null) {
|
||||
if(mv1.val < mv2.val) {
|
||||
mv.next = mv1;
|
||||
mv1 = mv1.next;
|
||||
}
|
||||
else {
|
||||
mv.next = mv2;
|
||||
mv2 = mv2.next;
|
||||
}
|
||||
mv = mv.next;
|
||||
}
|
||||
if(mv1 == null) {
|
||||
mv.next = mv2;
|
||||
}
|
||||
else {
|
||||
mv.next = mv1;
|
||||
}
|
||||
return head.next;
|
||||
}
|
||||
}
|
13
src/main/java/linkedlist/Node.java
Normal file
13
src/main/java/linkedlist/Node.java
Normal file
@ -0,0 +1,13 @@
|
||||
package linkedlist;
|
||||
|
||||
public class Node {
|
||||
int val;
|
||||
Node next;
|
||||
Node random;
|
||||
|
||||
public Node(int val) {
|
||||
this.val = val;
|
||||
this.next = null;
|
||||
this.random = null;
|
||||
}
|
||||
}
|
47
src/main/java/linkedlist/RemoveNthFromEnd.java
Normal file
47
src/main/java/linkedlist/RemoveNthFromEnd.java
Normal file
@ -0,0 +1,47 @@
|
||||
package linkedlist;
|
||||
|
||||
import java.util.Deque;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
|
||||
/**
|
||||
* 题目: 19. 删除链表的倒数第 N 个结点 (removeNthFromEnd)
|
||||
* 描述:给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点。
|
||||
|
||||
|
||||
* 链接:https://leetcode.cn/problems/remove-nth-node-from-end-of-list/
|
||||
|
||||
*/
|
||||
public class RemoveNthFromEnd {
|
||||
public ListNode removeNthFromEnd1(ListNode head, int n) {
|
||||
HashMap<Integer,ListNode>map=new HashMap<>();
|
||||
int k=0;
|
||||
ListNode cur=head;
|
||||
while (cur!=null){
|
||||
map.put(k++,cur);
|
||||
cur=cur.next;
|
||||
}
|
||||
if(k-n==0)
|
||||
return head.next;
|
||||
ListNode pre=map.get(k-n-1);
|
||||
pre.next= map.get(k-n+1);
|
||||
return head;
|
||||
}
|
||||
//入栈 出栈
|
||||
public ListNode removeNthFromEnd(ListNode head, int n) {
|
||||
ListNode dummy = new ListNode(0,head);
|
||||
Deque<ListNode> stack = new LinkedList<>();
|
||||
ListNode cur = dummy;
|
||||
while (cur != null) {
|
||||
stack.push(cur);
|
||||
cur = cur.next;
|
||||
}
|
||||
for (int i = 0; i < n; ++i) {
|
||||
stack.pop();
|
||||
}
|
||||
ListNode prev = stack.peek();
|
||||
prev.next = prev.next.next;
|
||||
ListNode ans = dummy.next;
|
||||
return ans;
|
||||
}
|
||||
}
|
31
src/main/java/linkedlist/SortList.java
Normal file
31
src/main/java/linkedlist/SortList.java
Normal file
@ -0,0 +1,31 @@
|
||||
package linkedlist;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 题目: 148. 排序链表 (sortList)
|
||||
* 描述:给你链表的头结点 head ,请将其按 升序 排列并返回 排序后的链表 。
|
||||
|
||||
* 链接:https://leetcode.cn/problems/sort-list/
|
||||
|
||||
*/
|
||||
public class SortList {
|
||||
public ListNode sortList(ListNode head) {
|
||||
ListNode cur=head;
|
||||
List<Integer>list=new ArrayList<>();
|
||||
while (cur!=null){
|
||||
list.add(cur.val);
|
||||
cur=cur.next;
|
||||
}
|
||||
Collections.sort(list);
|
||||
ListNode pre=new ListNode(-1);
|
||||
ListNode newnode=pre;
|
||||
for (Integer integer : list) {
|
||||
pre.next= new ListNode(integer);
|
||||
pre=pre.next;
|
||||
}
|
||||
return newnode.next;
|
||||
}
|
||||
}
|
41
src/main/java/linkedlist/SwapPairs.java
Normal file
41
src/main/java/linkedlist/SwapPairs.java
Normal file
@ -0,0 +1,41 @@
|
||||
package linkedlist;
|
||||
/**
|
||||
* 题目: 24. 两两交换链表中的节点 (swapPairs)
|
||||
* 描述:给你一个链表,两两交换其中相邻的节点,并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题(即,只能进行节点交换)。
|
||||
|
||||
|
||||
* 链接:https://leetcode.cn/problems/swap-nodes-in-pairs/
|
||||
|
||||
*/
|
||||
//需重做
|
||||
public class SwapPairs {
|
||||
//只有一个节点或没有节点时无需交换!
|
||||
//递归
|
||||
public ListNode swapPairs(ListNode head) {
|
||||
if (head == null || head.next == null) {
|
||||
return head;
|
||||
}
|
||||
ListNode one = head;
|
||||
ListNode two = one.next;
|
||||
ListNode three = two.next;
|
||||
|
||||
two.next = one;
|
||||
one.next = swapPairs(three);
|
||||
|
||||
return two;
|
||||
}
|
||||
//迭代,好理解
|
||||
public ListNode swapPairs1(ListNode head) {
|
||||
ListNode dummyHead = new ListNode(0,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;
|
||||
}
|
||||
}
|
@ -1,9 +1,6 @@
|
||||
package substring;
|
||||
|
||||
import hash.Test;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
|
||||
/**
|
||||
* 题目:523. 连续的子数组和 (checkSubarraySum)
|
||||
|
47
src/main/java/tree/InorderTraversal.java
Normal file
47
src/main/java/tree/InorderTraversal.java
Normal file
@ -0,0 +1,47 @@
|
||||
package tree;
|
||||
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Deque;
|
||||
import java.util.List;
|
||||
/**
|
||||
* 题目: 94. 二叉树的中序遍历 (inorderTraversal)
|
||||
* 描述:给定一个二叉树的根节点 root ,返回 它的 中序 遍历 。
|
||||
|
||||
* 链接:https://leetcode.cn/problems/binary-tree-inorder-traversal/
|
||||
|
||||
*/
|
||||
//递归会 迭代需记一下
|
||||
public class InorderTraversal {
|
||||
//递归
|
||||
public List<Integer> inorderTraversal(TreeNode root) {
|
||||
List<Integer> res = new ArrayList<>();
|
||||
inorder(root, res);
|
||||
return res;
|
||||
}
|
||||
|
||||
public void inorder(TreeNode root, List<Integer> res) {
|
||||
if (root == null) {
|
||||
return;
|
||||
}
|
||||
inorder(root.left, res);
|
||||
res.add(root.val);
|
||||
inorder(root.right, res);
|
||||
}
|
||||
|
||||
//迭代+栈
|
||||
public List<Integer> inorderTraversal1(TreeNode root) {
|
||||
List<Integer> res = new ArrayList<Integer>();
|
||||
Deque<TreeNode> stk = new ArrayDeque<>();
|
||||
while (root != null || !stk.isEmpty()) {
|
||||
while (root != null) {
|
||||
stk.push(root);
|
||||
root = root.left;
|
||||
}
|
||||
root = stk.pop();
|
||||
res.add(root.val);
|
||||
root = root.right;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
}
|
0
src/main/java/tree/MaxDepth.py
Normal file
0
src/main/java/tree/MaxDepth.py
Normal file
17
src/main/java/tree/TreeNode.java
Normal file
17
src/main/java/tree/TreeNode.java
Normal file
@ -0,0 +1,17 @@
|
||||
package tree;
|
||||
|
||||
public class TreeNode {
|
||||
int val;
|
||||
TreeNode left;
|
||||
TreeNode right;
|
||||
TreeNode() {
|
||||
}
|
||||
TreeNode(int val) {
|
||||
this.val = val;
|
||||
}
|
||||
TreeNode(int val, TreeNode left, TreeNode right) {
|
||||
this.val = val;
|
||||
this.left = left;
|
||||
this.right = right;
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user