diff --git a/src/main/java/linkedlist/AddTwoNumbers.java b/src/main/java/linkedlist/AddTwoNumbers.java new file mode 100644 index 0000000..37304d4 --- /dev/null +++ b/src/main/java/linkedlist/AddTwoNumbers.java @@ -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; + } +} diff --git a/src/main/java/linkedlist/CopyRandomList.java b/src/main/java/linkedlist/CopyRandomList.java new file mode 100644 index 0000000..0a8ecca --- /dev/null +++ b/src/main/java/linkedlist/CopyRandomList.java @@ -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 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); + } +} diff --git a/src/main/java/linkedlist/DetectCycle.java b/src/main/java/linkedlist/DetectCycle.java new file mode 100644 index 0000000..d8cae22 --- /dev/null +++ b/src/main/java/linkedlist/DetectCycle.java @@ -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 visited = new HashSet(); + 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; + } +} diff --git a/src/main/java/linkedlist/HasCycle.java b/src/main/java/linkedlist/HasCycle.java new file mode 100644 index 0000000..6c98c0d --- /dev/null +++ b/src/main/java/linkedlist/HasCycle.java @@ -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) { + HashSetset=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; + } +} diff --git a/src/main/java/linkedlist/ListNode.java b/src/main/java/linkedlist/ListNode.java index dd18f39..1f503fa 100644 --- a/src/main/java/linkedlist/ListNode.java +++ b/src/main/java/linkedlist/ListNode.java @@ -7,4 +7,5 @@ public class ListNode { val = x; next = null; } + ListNode(int val, ListNode next) { this.val = val; this.next = next; } } diff --git a/src/main/java/linkedlist/MergeTwoLists.java b/src/main/java/linkedlist/MergeTwoLists.java new file mode 100644 index 0000000..3ebd6a0 --- /dev/null +++ b/src/main/java/linkedlist/MergeTwoLists.java @@ -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; + } +} diff --git a/src/main/java/linkedlist/Node.java b/src/main/java/linkedlist/Node.java new file mode 100644 index 0000000..583905c --- /dev/null +++ b/src/main/java/linkedlist/Node.java @@ -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; + } +} diff --git a/src/main/java/linkedlist/RemoveNthFromEnd.java b/src/main/java/linkedlist/RemoveNthFromEnd.java new file mode 100644 index 0000000..e832445 --- /dev/null +++ b/src/main/java/linkedlist/RemoveNthFromEnd.java @@ -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) { + HashMapmap=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 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; + } +} diff --git a/src/main/java/linkedlist/SortList.java b/src/main/java/linkedlist/SortList.java new file mode 100644 index 0000000..16d6ffb --- /dev/null +++ b/src/main/java/linkedlist/SortList.java @@ -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; + Listlist=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; + } +} diff --git a/src/main/java/linkedlist/SwapPairs.java b/src/main/java/linkedlist/SwapPairs.java new file mode 100644 index 0000000..863ef35 --- /dev/null +++ b/src/main/java/linkedlist/SwapPairs.java @@ -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; + } +} diff --git a/src/main/java/substring/CheckSubarraySum.java b/src/main/java/substring/CheckSubarraySum.java index d4e2467..11cbf5d 100644 --- a/src/main/java/substring/CheckSubarraySum.java +++ b/src/main/java/substring/CheckSubarraySum.java @@ -1,9 +1,6 @@ package substring; -import hash.Test; - import java.util.HashMap; -import java.util.Iterator; /** * 题目:523. 连续的子数组和 (checkSubarraySum) diff --git a/src/main/java/tree/InorderTraversal.java b/src/main/java/tree/InorderTraversal.java new file mode 100644 index 0000000..42f2b62 --- /dev/null +++ b/src/main/java/tree/InorderTraversal.java @@ -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 inorderTraversal(TreeNode root) { + List res = new ArrayList<>(); + inorder(root, res); + return res; + } + + public void inorder(TreeNode root, List res) { + if (root == null) { + return; + } + inorder(root.left, res); + res.add(root.val); + inorder(root.right, res); + } + + //迭代+栈 + public List inorderTraversal1(TreeNode root) { + List res = new ArrayList(); + Deque 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; + } +} diff --git a/src/main/java/tree/MaxDepth.py b/src/main/java/tree/MaxDepth.py new file mode 100644 index 0000000..e69de29 diff --git a/src/main/java/tree/TreeNode.java b/src/main/java/tree/TreeNode.java new file mode 100644 index 0000000..c9ffa70 --- /dev/null +++ b/src/main/java/tree/TreeNode.java @@ -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; + } +}