diff --git "a/week01/[189]\346\227\213\350\275\254\346\225\260\347\273\204.java" "b/week01/[189]\346\227\213\350\275\254\346\225\260\347\273\204.java" new file mode 100644 index 00000000..58782896 --- /dev/null +++ "b/week01/[189]\346\227\213\350\275\254\346\225\260\347\273\204.java" @@ -0,0 +1,53 @@ +//给定一个数组,将数组中的元素向右移动 k 个位置,其中 k 是非负数。 +// +// 示例 1: +// +// 输入: [1,2,3,4,5,6,7] 和 k = 3 +//输出: [5,6,7,1,2,3,4] +//解释: +//向右旋转 1 步: [7,1,2,3,4,5,6] +//向右旋转 2 步: [6,7,1,2,3,4,5] +//向右旋转 3 步: [5,6,7,1,2,3,4] +// +// +// 示例 2: +// +// 输入: [-1,-100,3,99] 和 k = 2 +//输出: [3,99,-1,-100] +//解释: +//向右旋转 1 步: [99,-1,-100,3] +//向右旋转 2 步: [3,99,-1,-100] +// +// 说明: +// +// +// 尽可能想出更多的解决方案,至少有三种不同的方法可以解决这个问题。 +// 要求使用空间复杂度为 O(1) 的 原地 算法。 +// +// Related Topics 数组 +// 👍 720 👎 0 + + +//leetcode submit region begin(Prohibit modification and deletion) +class Solution { + public void rotate(int[] nums, int k) { + if (nums == null || nums.length == 0) { + return; + } + k %= nums.length; + reverseArray(nums, 0, nums.length - 1); + reverseArray(nums, 0, k - 1); + reverseArray(nums, k, nums.length - 1); + } + + private void reverseArray(int[] arr, int start, int end) { + while (start < end) { + int temp = arr[start]; + arr[start] = arr[end]; + arr[end] = temp; + start++; + end--; + } + } +} +//leetcode submit region end(Prohibit modification and deletion) diff --git "a/week01/[1]\344\270\244\346\225\260\344\271\213\345\222\214.java" "b/week01/[1]\344\270\244\346\225\260\344\271\213\345\222\214.java" new file mode 100644 index 00000000..72bc6b1d --- /dev/null +++ "b/week01/[1]\344\270\244\346\225\260\344\271\213\345\222\214.java" @@ -0,0 +1,35 @@ +//给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。 +// +// 你可以假设每种输入只会对应一个答案。但是,数组中同一个元素不能使用两遍。 +// +// +// +// 示例: +// +// 给定 nums = [2, 7, 11, 15], target = 9 +// +//因为 nums[0] + nums[1] = 2 + 7 = 9 +//所以返回 [0, 1] +// +// Related Topics 数组 哈希表 +// 👍 9415 👎 0 + + +import java.util.HashMap; + +//leetcode submit region begin(Prohibit modification and deletion) +class Solution { + public int[] twoSum(int[] nums, int target) { + HashMap map = new HashMap(); + for (int i = 0; i < nums.length; i++) { + int complement = target - nums[i]; + if (map.containsKey(complement)) { + return new int[]{map.get(complement), i}; + } else { + map.put(nums[i], i); + } + } + return null; + } +} +//leetcode submit region end(Prohibit modification and deletion) diff --git "a/week01/[21]\345\220\210\345\271\266\344\270\244\344\270\252\346\234\211\345\272\217\351\223\276\350\241\250.java" "b/week01/[21]\345\220\210\345\271\266\344\270\244\344\270\252\346\234\211\345\272\217\351\223\276\350\241\250.java" new file mode 100644 index 00000000..deaa0c80 --- /dev/null +++ "b/week01/[21]\345\220\210\345\271\266\344\270\244\344\270\252\346\234\211\345\272\217\351\223\276\350\241\250.java" @@ -0,0 +1,52 @@ +//将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 +// +// +// +// 示例: +// +// 输入:1->2->4, 1->3->4 +//输出:1->1->2->3->4->4 +// +// Related Topics 链表 +// 👍 1340 👎 0 + + +//leetcode submit region begin(Prohibit modification and deletion) +/** + * 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 mergeTwoLists(ListNode l1, ListNode l2) { + ListNode dummy = new ListNode(0); + ListNode curr = dummy; + if (l1 == null && l2 == null) { + return null; + } + while (l1 != null && l2 != null) { + if (l1.val < l2.val) { + curr.next = l1; + l1 = l1.next; + curr = curr.next; + } else { + curr.next = l2; + l2 = l2.next; + curr = curr.next; + } + } + if (l1 != null) { + curr.next = l1; + } + if (l2 != null) { + curr.next = l2; + } + return dummy.next; + } +} +//leetcode submit region end(Prohibit modification and deletion) diff --git "a/week01/[26]\345\210\240\351\231\244\346\216\222\345\272\217\346\225\260\347\273\204\344\270\255\347\232\204\351\207\215\345\244\215\351\241\271.java" "b/week01/[26]\345\210\240\351\231\244\346\216\222\345\272\217\346\225\260\347\273\204\344\270\255\347\232\204\351\207\215\345\244\215\351\241\271.java" new file mode 100644 index 00000000..1cbb1afd --- /dev/null +++ "b/week01/[26]\345\210\240\351\231\244\346\216\222\345\272\217\346\225\260\347\273\204\344\270\255\347\232\204\351\207\215\345\244\215\351\241\271.java" @@ -0,0 +1,60 @@ +//给定一个排序数组,你需要在 原地 删除重复出现的元素,使得每个元素只出现一次,返回移除后数组的新长度。 +// +// 不要使用额外的数组空间,你必须在 原地 修改输入数组 并在使用 O(1) 额外空间的条件下完成。 +// +// +// +// 示例 1: +// +// 给定数组 nums = [1,1,2], +// +//函数应该返回新的长度 2, 并且原数组 nums 的前两个元素被修改为 1, 2。 +// +//你不需要考虑数组中超出新长度后面的元素。 +// +// 示例 2: +// +// 给定 nums = [0,0,1,1,1,2,2,3,3,4], +// +//函数应该返回新的长度 5, 并且原数组 nums 的前五个元素被修改为 0, 1, 2, 3, 4。 +// +//你不需要考虑数组中超出新长度后面的元素。 +// +// +// +// +// 说明: +// +// 为什么返回数值是整数,但输出的答案是数组呢? +// +// 请注意,输入数组是以「引用」方式传递的,这意味着在函数里修改输入数组对于调用者是可见的。 +// +// 你可以想象内部操作如下: +// +// // nums 是以“引用”方式传递的。也就是说,不对实参做任何拷贝 +//int len = removeDuplicates(nums); +// +//// 在函数里修改输入数组对于调用者是可见的。 +//// 根据你的函数返回的长度, 它会打印出数组中该长度范围内的所有元素。 +//for (int i = 0; i < len; i++) { +//    print(nums[i]); +//} +// +// Related Topics 数组 双指针 +// 👍 1686 👎 0 + + +//leetcode submit region begin(Prohibit modification and deletion) +class Solution { + public int removeDuplicates(int[] nums) { + int pos = 0; + for (int i = 1; i < nums.length; i++) { + if (nums[i] != nums[pos]) { + pos++; + nums[pos] = nums[i]; + } + } + return pos + 1; + } +} +//leetcode submit region end(Prohibit modification and deletion) diff --git "a/week01/[283]\347\247\273\345\212\250\351\233\266.java" "b/week01/[283]\347\247\273\345\212\250\351\233\266.java" new file mode 100644 index 00000000..274a3b1a --- /dev/null +++ "b/week01/[283]\347\247\273\345\212\250\351\233\266.java" @@ -0,0 +1,37 @@ +//给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。 +// +// 示例: +// +// 输入: [0,1,0,3,12] +//输出: [1,3,12,0,0] +// +// 说明: +// +// +// 必须在原数组上操作,不能拷贝额外的数组。 +// 尽量减少操作次数。 +// +// Related Topics 数组 双指针 +// 👍 777 👎 0 + + +//leetcode submit region begin(Prohibit modification and deletion) +class Solution { + public void moveZeroes(int[] nums) { + if (nums == null || nums.length == 0) { + return; + } + int pos = 0; + for (int i = 0; i < nums.length; i++) { + if (nums[i] != 0) { + nums[pos] = nums[i]; + pos++; + } + } + while (pos < nums.length) { + nums[pos] = 0; + pos++; + } + } +} +//leetcode submit region end(Prohibit modification and deletion) diff --git "a/week01/[42]\346\216\245\351\233\250\346\260\264.java" "b/week01/[42]\346\216\245\351\233\250\346\260\264.java" new file mode 100644 index 00000000..8faa9060 --- /dev/null +++ "b/week01/[42]\346\216\245\351\233\250\346\260\264.java" @@ -0,0 +1,59 @@ +//给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。 +// +// +// +// 示例 1: +// +// +// +// +//输入:height = [0,1,0,2,1,0,1,3,2,1,2,1] +//输出:6 +//解释:上面是由数组 [0,1,0,2,1,0,1,3,2,1,2,1] 表示的高度图,在这种情况下,可以接 6 个单位的雨水(蓝色部分表示雨水)。 +// +// +// 示例 2: +// +// +//输入:height = [4,2,0,3,2,5] +//输出:9 +// +// +// +// +// 提示: +// +// +// n == height.length +// 0 <= n <= 3 * 104 +// 0 <= height[i] <= 105 +// +// Related Topics 栈 数组 双指针 +// 👍 1768 👎 0 + + +//leetcode submit region begin(Prohibit modification and deletion) +class Solution { + public int trap(int[] height) { + if (height == null || height.length == 0) { + return 0; + } + int len = height.length; + int[] leftMax = new int[len]; + int[] rightMax = new int[len]; + leftMax[0] = height[0]; + rightMax[len - 1] = height[len - 1]; + for (int i = 1; i < len; i++) { + leftMax[i] = Math.max(leftMax[i - 1], height[i]); + } + for (int i = len - 2; i >= 0; i--) { + rightMax[i] = Math.max(rightMax[i + 1], height[i]); + } + int sum = 0; + for (int i = 0; i < len; i++) { + sum += Math.min(leftMax[i], rightMax[i]) - height[i]; + } + return sum; + } +} +//leetcode submit region end(Prohibit modification and deletion) diff --git "a/week01/[641]\350\256\276\350\256\241\345\276\252\347\216\257\345\217\214\347\253\257\351\230\237\345\210\227.java" "b/week01/[641]\350\256\276\350\256\241\345\276\252\347\216\257\345\217\214\347\253\257\351\230\237\345\210\227.java" new file mode 100644 index 00000000..4a9c6a7a --- /dev/null +++ "b/week01/[641]\350\256\276\350\256\241\345\276\252\347\216\257\345\217\214\347\253\257\351\230\237\345\210\227.java" @@ -0,0 +1,142 @@ +//设计实现双端队列。 +//你的实现需要支持以下操作: +// +// +// MyCircularDeque(k):构造函数,双端队列的大小为k。 +// insertFront():将一个元素添加到双端队列头部。 如果操作成功返回 true。 +// insertLast():将一个元素添加到双端队列尾部。如果操作成功返回 true。 +// deleteFront():从双端队列头部删除一个元素。 如果操作成功返回 true。 +// deleteLast():从双端队列尾部删除一个元素。如果操作成功返回 true。 +// getFront():从双端队列头部获得一个元素。如果双端队列为空,返回 -1。 +// getRear():获得双端队列的最后一个元素。 如果双端队列为空,返回 -1。 +// isEmpty():检查双端队列是否为空。 +// isFull():检查双端队列是否满了。 +// +// +// 示例: +// +// MyCircularDeque circularDeque = new MycircularDeque(3); // 设置容量大小为3 +//circularDeque.insertLast(1); // 返回 true +//circularDeque.insertLast(2); // 返回 true +//circularDeque.insertFront(3); // 返回 true +//circularDeque.insertFront(4); // 已经满了,返回 false +//circularDeque.getRear(); // 返回 2 +//circularDeque.isFull(); // 返回 true +//circularDeque.deleteLast(); // 返回 true +//circularDeque.insertFront(4); // 返回 true +//circularDeque.getFront(); // 返回 4 +//  +// +// +// +// 提示: +// +// +// 所有值的范围为 [1, 1000] +// 操作次数的范围为 [1, 1000] +// 请不要使用内置的双端队列库。 +// +// Related Topics 设计 队列 +// 👍 60 👎 0 + + +//leetcode submit region begin(Prohibit modification and deletion) +class MyCircularDeque { + + int[] arr; + int size; + int capacity; + int front; + int rear; + + /** Initialize your data structure here. Set the size of the deque to be k. */ + public MyCircularDeque(int k) { + capacity = k; + size = 0; + front = 0; + rear = 0; + arr = new int[capacity]; + } + + /** Adds an item at the front of Deque. Return true if the operation is successful. */ + public boolean insertFront(int value) { + if (size == capacity) { + return false; + } + arr[front] = value; + front = (front + 1) % capacity; + size++; + return true; + } + + /** Adds an item at the rear of Deque. Return true if the operation is successful. */ + public boolean insertLast(int value) { + if (size == capacity) { + return false; + } + rear = (rear - 1 + capacity) % capacity; + arr[rear] = value; + size++; + return true; + } + + /** Deletes an item from the front of Deque. Return true if the operation is successful. */ + public boolean deleteFront() { + if (size == 0) { + return false; + } + front = (front - 1 + capacity) % capacity; + size--; + return true; + } + + /** Deletes an item from the rear of Deque. Return true if the operation is successful. */ + public boolean deleteLast() { + if (size == 0) { + return false; + } + rear = (rear + 1) % capacity; + size--; + return true; + } + + /** Get the front item from the deque. */ + public int getFront() { + if (size == 0) { + return -1; + } + return arr[(front - 1 + capacity) % capacity]; + } + + /** Get the last item from the deque. */ + public int getRear() { + if (size == 0) { + return -1; + } + return arr[rear]; + } + + /** Checks whether the circular deque is empty or not. */ + public boolean isEmpty() { + return size == 0; + } + + /** Checks whether the circular deque is full or not. */ + public boolean isFull() { + return size == capacity; + } +} + +/** + * Your MyCircularDeque object will be instantiated and called as such: + * MyCircularDeque obj = new MyCircularDeque(k); + * boolean param_1 = obj.insertFront(value); + * boolean param_2 = obj.insertLast(value); + * boolean param_3 = obj.deleteFront(); + * boolean param_4 = obj.deleteLast(); + * int param_5 = obj.getFront(); + * int param_6 = obj.getRear(); + * boolean param_7 = obj.isEmpty(); + * boolean param_8 = obj.isFull(); + */ +//leetcode submit region end(Prohibit modification and deletion) diff --git "a/week01/[66]\345\212\240\344\270\200.java" "b/week01/[66]\345\212\240\344\270\200.java" new file mode 100644 index 00000000..93d1d567 --- /dev/null +++ "b/week01/[66]\345\212\240\344\270\200.java" @@ -0,0 +1,44 @@ +//给定一个由整数组成的非空数组所表示的非负整数,在该数的基础上加一。 +// +// 最高位数字存放在数组的首位, 数组中每个元素只存储单个数字。 +// +// 你可以假设除了整数 0 之外,这个整数不会以零开头。 +// +// 示例 1: +// +// 输入: [1,2,3] +//输出: [1,2,4] +//解释: 输入数组表示数字 123。 +// +// +// 示例 2: +// +// 输入: [4,3,2,1] +//输出: [4,3,2,2] +//解释: 输入数组表示数字 4321。 +// +// Related Topics 数组 +// 👍 565 👎 0 + + +//leetcode submit region begin(Prohibit modification and deletion) +class Solution { + public int[] plusOne(int[] digits) { + for (int i = digits.length - 1; i >= 0; i--) { + digits[i] += 1; + if (digits[i] != 10) { + break; + } else { + digits[i] = 0; + } + } + if (digits[0] == 0) { + int[] res = new int[digits.length + 1]; + res[0] = 1; + System.arraycopy(digits, 0, res, 1, digits.length); + return res; + } + return digits; + } +} +//leetcode submit region end(Prohibit modification and deletion) diff --git "a/week01/[88]\345\220\210\345\271\266\344\270\244\344\270\252\346\234\211\345\272\217\346\225\260\347\273\204.java" "b/week01/[88]\345\220\210\345\271\266\344\270\244\344\270\252\346\234\211\345\272\217\346\225\260\347\273\204.java" new file mode 100644 index 00000000..b8d78f3b --- /dev/null +++ "b/week01/[88]\345\220\210\345\271\266\344\270\244\344\270\252\346\234\211\345\272\217\346\225\260\347\273\204.java" @@ -0,0 +1,52 @@ +//给你两个有序整数数组 nums1 和 nums2,请你将 nums2 合并到 nums1 中,使 nums1 成为一个有序数组。 +// +// +// +// 说明: +// +// +// 初始化 nums1 和 nums2 的元素数量分别为 m 和 n 。 +// 你可以假设 nums1 有足够的空间(空间大小大于或等于 m + n)来保存 nums2 中的元素。 +// +// +// +// +// 示例: +// +// +//输入: +//nums1 = [1,2,3,0,0,0], m = 3 +//nums2 = [2,5,6], n = 3 +// +//输出:[1,2,2,3,5,6] +// +// +// +// 提示: +// +// +// -10^9 <= nums1[i], nums2[i] <= 10^9 +// nums1.length == m + n +// nums2.length == n +// +// Related Topics 数组 双指针 +// 👍 669 👎 0 + + +//leetcode submit region begin(Prohibit modification and deletion) +class Solution { + public void merge(int[] nums1, int m, int[] nums2, int n) { + int pos = m + n - 1, index1 = m - 1, index2 = n - 1; + while (index1 >= 0 && index2 >= 0) { + if (nums1[index1] > nums2[index2]) { + nums1[pos--] = nums1[index1--]; + } else { + nums1[pos--] = nums2[index2--]; + } + } + while (index2 >= 0) { + nums1[pos--] = nums2[index2--]; + } + } +} +//leetcode submit region end(Prohibit modification and deletion) diff --git "a/week01/\346\224\271\345\206\231Deque\344\273\243\347\240\201.java" "b/week01/\346\224\271\345\206\231Deque\344\273\243\347\240\201.java" new file mode 100644 index 00000000..58f69b17 --- /dev/null +++ "b/week01/\346\224\271\345\206\231Deque\344\273\243\347\240\201.java" @@ -0,0 +1,15 @@ +Deque deque = new LinkedList(); + +deque.addFirst("a"); +deque.addFirst("b"); +deque.addFirst("c"); +System.out.println(deque); + +String str = deque.getFirst(); +System.out.println(str); +System.out.println(deque); + +while (deque.size() > 0) { + System.out.println(deque.removeFirst()); +} +System.out.println(deque); diff --git "a/week02/[144]\344\272\214\345\217\211\346\240\221\347\232\204\345\211\215\345\272\217\351\201\215\345\216\206.java" "b/week02/[144]\344\272\214\345\217\211\346\240\221\347\232\204\345\211\215\345\272\217\351\201\215\345\216\206.java" new file mode 100644 index 00000000..3d2c9afe --- /dev/null +++ "b/week02/[144]\344\272\214\345\217\211\346\240\221\347\232\204\345\211\215\345\272\217\351\201\215\345\216\206.java" @@ -0,0 +1,77 @@ +//给定一个二叉树,返回它的 前序 遍历。 +// +// 示例: +// +// 输入: [1,null,2,3] +// 1 +// \ +// 2 +// / +// 3 +// +//输出: [1,2,3] +// +// +// 进阶: 递归算法很简单,你可以通过迭代算法完成吗? +// Related Topics 栈 树 +// 👍 422 👎 0 + + +//leetcode submit region begin(Prohibit modification and deletion) + +import java.util.ArrayList; +import java.util.Stack; + +/** + * Definition for a binary tree node. + * 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; + * } + * } + */ +class Solution { + public List preorderTraversal(TreeNode root) { + List list = new ArrayList<>(); + preorder(list, root); + return list; + } + + private void preorder(List list, TreeNode root) { + if (root != null) { + list.add(root.val); + preorder(list, root.left); + preorder(list, root.right); + } + return; + } + + public List preorderTraversal(TreeNode root) { + List list = new ArrayList<>(); + if (root == null) { + return list; + } + Stack stack = new Stack(); + TreeNode p = root; + stack.push(p); + while (!stack.isEmpty()) { + p = stack.pop(); + list.add(p.val); + if (p.right != null) { + stack.push(p.right); + } + if (p.left != null) { + stack.push(p.left); + } + } + return list; + } +} +//leetcode submit region end(Prohibit modification and deletion) diff --git "a/week02/[1]\344\270\244\346\225\260\344\271\213\345\222\214.java" "b/week02/[1]\344\270\244\346\225\260\344\271\213\345\222\214.java" new file mode 100644 index 00000000..72bc6b1d --- /dev/null +++ "b/week02/[1]\344\270\244\346\225\260\344\271\213\345\222\214.java" @@ -0,0 +1,35 @@ +//给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。 +// +// 你可以假设每种输入只会对应一个答案。但是,数组中同一个元素不能使用两遍。 +// +// +// +// 示例: +// +// 给定 nums = [2, 7, 11, 15], target = 9 +// +//因为 nums[0] + nums[1] = 2 + 7 = 9 +//所以返回 [0, 1] +// +// Related Topics 数组 哈希表 +// 👍 9415 👎 0 + + +import java.util.HashMap; + +//leetcode submit region begin(Prohibit modification and deletion) +class Solution { + public int[] twoSum(int[] nums, int target) { + HashMap map = new HashMap(); + for (int i = 0; i < nums.length; i++) { + int complement = target - nums[i]; + if (map.containsKey(complement)) { + return new int[]{map.get(complement), i}; + } else { + map.put(nums[i], i); + } + } + return null; + } +} +//leetcode submit region end(Prohibit modification and deletion) diff --git "a/week02/[242]\346\234\211\346\225\210\347\232\204\345\255\227\346\257\215\345\274\202\344\275\215\350\257\215.java" "b/week02/[242]\346\234\211\346\225\210\347\232\204\345\255\227\346\257\215\345\274\202\344\275\215\350\257\215.java" new file mode 100644 index 00000000..1a540364 --- /dev/null +++ "b/week02/[242]\346\234\211\346\225\210\347\232\204\345\255\227\346\257\215\345\274\202\344\275\215\350\257\215.java" @@ -0,0 +1,45 @@ +//给定两个字符串 s 和 t ,编写一个函数来判断 t 是否是 s 的字母异位词。 +// +// 示例 1: +// +// 输入: s = "anagram", t = "nagaram" +//输出: true +// +// +// 示例 2: +// +// 输入: s = "rat", t = "car" +//输出: false +// +// 说明: +//你可以假设字符串只包含小写字母。 +// +// 进阶: +//如果输入字符串包含 unicode 字符怎么办?你能否调整你的解法来应对这种情况? +// Related Topics 排序 哈希表 +// 👍 265 👎 0 + + +import java.util.HashSet; + +//leetcode submit region begin(Prohibit modification and deletion) +class Solution { + public boolean isAnagram(String s, String t) { + if (s.length() != t.length()) { + return false; + } + int[] hash = new int[26]; + for (int i = 0; i < s.length(); i++) { + hash[s.charAt(i) - 'a']++; + hash[t.charAt(i) - 'a']--; + } + + for (int i = 0; i < hash.length; i++) { + if (hash[i] != 0) { + return false; + } + } + return true; + } +} +//leetcode submit region end(Prohibit modification and deletion) diff --git "a/week02/[264]\344\270\221\346\225\260 II.java" "b/week02/[264]\344\270\221\346\225\260 II.java" new file mode 100644 index 00000000..56d93ee9 --- /dev/null +++ "b/week02/[264]\344\270\221\346\225\260 II.java" @@ -0,0 +1,42 @@ +//编写一个程序,找出第 n 个丑数。 +// +// 丑数就是质因数只包含 2, 3, 5 的正整数。 +// +// 示例: +// +// 输入: n = 10 +//输出: 12 +//解释: 1, 2, 3, 4, 5, 6, 8, 9, 10, 12 是前 10 个丑数。 +// +// 说明: +// +// +// 1 是丑数。 +// n 不超过1690。 +// +// Related Topics 堆 数学 动态规划 +// 👍 417 👎 0 + + +//leetcode submit region begin(Prohibit modification and deletion) +class Solution { + public int nthUglyNumber(int n) { + int[] nums = new int[n]; + int index2 = 0, index3 = 0, index5 = 0; + nums[0] = 1; + for (int i = 1; i < nums.length; i++) { + nums[i] = Math.min(nums[index2] * 2, Math.min(nums[index3] * 3, nums[index5] * 5)); + if (nums[i] == nums[index2] * 2) { + index2++; + } + if (nums[i] == nums[index3] * 3) { + index3++; + } + if (nums[i] == nums[index5] * 5) { + index5++; + } + } + return nums[n - 1]; + } +} +//leetcode submit region end(Prohibit modification and deletion) diff --git "a/week02/[347]\345\211\215 K \344\270\252\351\253\230\351\242\221\345\205\203\347\264\240.java" "b/week02/[347]\345\211\215 K \344\270\252\351\253\230\351\242\221\345\205\203\347\264\240.java" new file mode 100644 index 00000000..5242ee4b --- /dev/null +++ "b/week02/[347]\345\211\215 K \344\270\252\351\253\230\351\242\221\345\205\203\347\264\240.java" @@ -0,0 +1,84 @@ +//给定一个非空的整数数组,返回其中出现频率前 k 高的元素。 +// +// +// +// 示例 1: +// +// 输入: nums = [1,1,1,2,2,3], k = 2 +//输出: [1,2] +// +// +// 示例 2: +// +// 输入: nums = [1], k = 1 +//输出: [1] +// +// +// +// 提示: +// +// +// 你可以假设给定的 k 总是合理的,且 1 ≤ k ≤ 数组中不相同的元素的个数。 +// 你的算法的时间复杂度必须优于 O(n log n) , n 是数组的大小。 +// 题目数据保证答案唯一,换句话说,数组中前 k 个高频元素的集合是唯一的。 +// 你可以按任意顺序返回答案。 +// +// Related Topics 堆 哈希表 +// 👍 555 👎 0 + + +import java.util.Map; +import java.util.PriorityQueue; + +//leetcode submit region begin(Prohibit modification and deletion) +// 1. bucket sort +//class Solution { +// public int[] topKFrequent(int[] nums, int k) { +// Map map = new HashMap<>(); +// for (int num : nums) { +// map.put(num, map.getOrDefault(num, 0) + 1); +// } +// List[] bucket = new List[nums.length + 1]; +// +// for (int key : map.keySet()) { +// int frequency = map.get(key); +// if (bucket[frequency] == null) { +// bucket[frequency] = new ArrayList<>(); +// } +// bucket[frequency].add(key); +// } +// +// int[] res = new int[k]; +// int count = 0; +// for (int i = bucket.length - 1; i >= 0 && count < k; i--) { +// if (bucket[i] != null) { +// for (int num : bucket[i]) { +// res[count++] = num; +// } +// } +// } +// return res; +// } +//} +// 2. priority queue +class Solution { + public int[] topKFrequent(int[] nums, int k) { + Map map = new HashMap<>(); + for (int num : nums) { + map.put(num, map.getOrDefault(num, 0) + 1); + } + PriorityQueue> maxHeap = + new PriorityQueue<>((a,b)->(b.getValue()-a.getValue())); + for (Map.Entry entry : map.entrySet()) { + maxHeap.add(entry); + } + int[] res = new int[k]; + int count = 0; + while (count < k) { + Map.Entry entry = maxHeap.poll(); + res[count++] = entry.getKey(); + } + return res; + } +} +//leetcode submit region end(Prohibit modification and deletion) diff --git "a/week02/[49]\345\255\227\346\257\215\345\274\202\344\275\215\350\257\215\345\210\206\347\273\204.java" "b/week02/[49]\345\255\227\346\257\215\345\274\202\344\275\215\350\257\215\345\210\206\347\273\204.java" new file mode 100644 index 00000000..84a74d88 --- /dev/null +++ "b/week02/[49]\345\255\227\346\257\215\345\274\202\344\275\215\350\257\215\345\210\206\347\273\204.java" @@ -0,0 +1,55 @@ +//给定一个字符串数组,将字母异位词组合在一起。字母异位词指字母相同,但排列不同的字符串。 +// +// 示例: +// +// 输入: ["eat", "tea", "tan", "ate", "nat", "bat"] +//输出: +//[ +// ["ate","eat","tea"], +// ["nat","tan"], +// ["bat"] +//] +// +// 说明: +// +// +// 所有输入均为小写字母。 +// 不考虑答案输出的顺序。 +// +// Related Topics 哈希表 字符串 +// 👍 502 👎 0 + + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; + +//leetcode submit region begin(Prohibit modification and deletion) +class Solution { + public List> groupAnagrams(String[] strs) { + if (strs == null || strs.length == 0) { + return new ArrayList<>(); + } + Map> map = new HashMap<>(); + for (String str : strs) { + int[] hash = new int[26]; + for (int i = 0; i < str.length(); i++) { + char c = str.charAt(i); + hash[c - 'a']++; + } + StringBuilder sb = new StringBuilder(); + for (int count : hash) { + sb.append('#'); + sb.append(count); + } + String id = sb.toString(); + if (!map.containsKey(id)) { + map.put(id, new ArrayList<>()); + } + map.get(id).add(str); + } + return new ArrayList<>(map.values()); + } +} +//leetcode submit region end(Prohibit modification and deletion) diff --git "a/week02/[589]N\345\217\211\346\240\221\347\232\204\345\211\215\345\272\217\351\201\215\345\216\206.java" "b/week02/[589]N\345\217\211\346\240\221\347\232\204\345\211\215\345\272\217\351\201\215\345\216\206.java" new file mode 100644 index 00000000..dd47b861 --- /dev/null +++ "b/week02/[589]N\345\217\211\346\240\221\347\232\204\345\211\215\345\272\217\351\201\215\345\216\206.java" @@ -0,0 +1,80 @@ +//给定一个 N 叉树,返回其节点值的前序遍历。 +// +// 例如,给定一个 3叉树 : +// +// +// +// +// +// +// +// 返回其前序遍历: [1,3,5,6,2,4]。 +// +// +// +// 说明: 递归法很简单,你可以使用迭代法完成此题吗? Related Topics 树 +// 👍 111 👎 0 + + +//leetcode submit region begin(Prohibit modification and deletion) +/* +// Definition for a Node. +class Node { + public int val; + public List children; + + public Node() {} + + public Node(int _val) { + val = _val; + } + + public Node(int _val, List _children) { + val = _val; + children = _children; + } +}; +*/ + + +import java.util.Stack; + +class Solution { +// public List preorder(Node root) { +// List list = new ArrayList<>(); +// if (root == null) { +// return list; +// } +// helper(root, list); +// return list; +// } +// +// private void helper(Node node, List list) { +// if (node != null) { +// list.add(node.val); +// for (Node child : node.children) { +// helper(child, list); +// } +// } +// return; +// } + + public List preorder(Node root) { + List list = new ArrayList<>(); + if (root == null) { + return list; + } + Stack stack = new Stack<>(); + Node p = root; + stack.push(p); + while (!stack.isEmpty()) { + p = stack.pop(); + list.add(p.val); + for (int i = p.children.size() - 1; i >= 0; i--) { + stack.push(p.children.get(i)); + } + } + return list; + } +} +//leetcode submit region end(Prohibit modification and deletion) diff --git "a/week02/[94]\344\272\214\345\217\211\346\240\221\347\232\204\344\270\255\345\272\217\351\201\215\345\216\206.java" "b/week02/[94]\344\272\214\345\217\211\346\240\221\347\232\204\344\270\255\345\272\217\351\201\215\345\216\206.java" new file mode 100644 index 00000000..c7c03b35 --- /dev/null +++ "b/week02/[94]\344\272\214\345\217\211\346\240\221\347\232\204\344\270\255\345\272\217\351\201\215\345\216\206.java" @@ -0,0 +1,73 @@ +//给定一个二叉树,返回它的中序 遍历。 +// +// 示例: +// +// 输入: [1,null,2,3] +// 1 +// \ +// 2 +// / +// 3 +// +//输出: [1,3,2] +// +// 进阶: 递归算法很简单,你可以通过迭代算法完成吗? +// Related Topics 栈 树 哈希表 +// 👍 757 👎 0 + + +//leetcode submit region begin(Prohibit modification and deletion) + +import java.util.ArrayList; +import java.util.List; +import java.util.Stack; + +/** + * Definition for a binary tree node. + * 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; + * } + * } + */ +class Solution { + public List inorderTraversal(TreeNode root) { + List list = new ArrayList<>(); + helper(root, list); + return list; + } + + public void helper(TreeNode root, List list) { + if (root != null) { + helper(root.left, list); + list.add(root.val); + helper(root.right, list); + } + return; + } +} +class Solution { + public List inorderTraversal(TreeNode root) { + List list = new ArrayList<>(); + Stack stack = new Stack<>(); + TreeNode curr = root; + while (curr != null || !stack.isEmpty()) { + while (curr != null) { + stack.push(curr); + curr = curr.left; + } + curr = stack.pop(); + list.add(curr.val); + curr = curr.right; + } + return list; + } +} +//leetcode submit region end(Prohibit modification and deletion) diff --git "a/week03/[105]\344\273\216\345\211\215\345\272\217\344\270\216\344\270\255\345\272\217\351\201\215\345\216\206\345\272\217\345\210\227\346\236\204\351\200\240\344\272\214\345\217\211\346\240\221.java" "b/week03/[105]\344\273\216\345\211\215\345\272\217\344\270\216\344\270\255\345\272\217\351\201\215\345\216\206\345\272\217\345\210\227\346\236\204\351\200\240\344\272\214\345\217\211\346\240\221.java" new file mode 100644 index 00000000..80961cbd --- /dev/null +++ "b/week03/[105]\344\273\216\345\211\215\345\272\217\344\270\216\344\270\255\345\272\217\351\201\215\345\216\206\345\272\217\345\210\227\346\236\204\351\200\240\344\272\214\345\217\211\346\240\221.java" @@ -0,0 +1,53 @@ +//根据一棵树的前序遍历与中序遍历构造二叉树。 +// +// 注意: +//你可以假设树中没有重复的元素。 +// +// 例如,给出 +// +// 前序遍历 preorder = [3,9,20,15,7] +//中序遍历 inorder = [9,3,15,20,7] +// +// 返回如下的二叉树: +// +// 3 +// / \ +// 9 20 +// / \ +// 15 7 +// Related Topics 树 深度优先搜索 数组 +// 👍 746 👎 0 + + +//leetcode submit region begin(Prohibit modification and deletion) +/** + * Definition for a binary tree node. + * public class TreeNode { + * int val; + * TreeNode left; + * TreeNode right; + * TreeNode(int x) { val = x; } + * } + */ +class Solution { + public TreeNode buildTree(int[] preorder, int[] inorder) { + return helper(0, 0, inorder.length - 1, preorder, inorder); + } + + public TreeNode helper(int preStart, int inStart, int inEnd, int[] preorder, int[] inorder) { + if (preStart > preorder.length - 1 || inStart > inEnd) { + return null; + } + TreeNode root = new TreeNode(preorder[preStart]); + int inIndex = 0; // Index of current root in inorder + for (int i = inStart; i <= inEnd; i++) { + if (inorder[i] == root.val) { + inIndex = i; + } + } + root.left = helper(preStart + 1, inStart, inIndex - 1, preorder, inorder); + root.right = helper(preStart + inIndex - inStart + 1, inIndex + 1, inEnd, preorder, inorder); + return root; + } +} +//leetcode submit region end(Prohibit modification and deletion) diff --git "a/week03/[236]\344\272\214\345\217\211\346\240\221\347\232\204\346\234\200\350\277\221\345\205\254\345\205\261\347\245\226\345\205\210.java" "b/week03/[236]\344\272\214\345\217\211\346\240\221\347\232\204\346\234\200\350\277\221\345\205\254\345\205\261\347\245\226\345\205\210.java" new file mode 100644 index 00000000..910f3e78 --- /dev/null +++ "b/week03/[236]\344\272\214\345\217\211\346\240\221\347\232\204\346\234\200\350\277\221\345\205\254\345\205\261\347\245\226\345\205\210.java" @@ -0,0 +1,72 @@ +//给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。 +// +// 百度百科中最近公共祖先的定义为:“对于有根树 T 的两个结点 p、q,最近公共祖先表示为一个结点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大( +//一个节点也可以是它自己的祖先)。” +// +// 例如,给定如下二叉树: root = [3,5,1,6,2,0,8,null,null,7,4] +// +// +// +// +// +// 示例 1: +// +// 输入: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 1 +//输出: 3 +//解释: 节点 5 和节点 1 的最近公共祖先是节点 3。 +// +// +// 示例 2: +// +// 输入: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 4 +//输出: 5 +//解释: 节点 5 和节点 4 的最近公共祖先是节点 5。因为根据定义最近公共祖先节点可以为节点本身。 +// +// +// +// +// 说明: +// +// +// 所有节点的值都是唯一的。 +// p、q 为不同节点且均存在于给定的二叉树中。 +// +// Related Topics 树 +// 👍 819 👎 0 + + +//leetcode submit region begin(Prohibit modification and deletion) +/** + * Definition for a binary tree node. + * public class TreeNode { + * int val; + * TreeNode left; + * TreeNode right; + * TreeNode(int x) { val = x; } + * } + */ +class Solution { + public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) { + if (root == null || root == p || root == q) { + return root; + } + TreeNode left = lowestCommonAncestor(root.left, p, q); + TreeNode right = lowestCommonAncestor(root.right, p, q); + + if (left != null && right != null) { + return root; // got lca + } + + // lca or A or B + if (left != null) { + return left; + } + if (right != null) { + return right; + } + + // left & right == null + return null; + } +} +//leetcode submit region end(Prohibit modification and deletion) diff --git "a/week03/[46]\345\205\250\346\216\222\345\210\227.java" "b/week03/[46]\345\205\250\346\216\222\345\210\227.java" new file mode 100644 index 00000000..9fc29346 --- /dev/null +++ "b/week03/[46]\345\205\250\346\216\222\345\210\227.java" @@ -0,0 +1,56 @@ +//给定一个 没有重复 数字的序列,返回其所有可能的全排列。 +// +// 示例: +// +// 输入: [1,2,3] +//输出: +//[ +// [1,2,3], +// [1,3,2], +// [2,1,3], +// [2,3,1], +// [3,1,2], +// [3,2,1] +//] +// Related Topics 回溯算法 +// 👍 982 👎 0 + + +import java.util.ArrayList; +import java.util.HashSet; + +//leetcode submit region begin(Prohibit modification and deletion) +class Solution { + public List> permute(int[] nums) { + List> result = new ArrayList<>(); + if (nums == null || nums.length == 0) { + return result; + } + List list = new ArrayList<>(); + boolean[] visited = new boolean[nums.length]; + helper(result, list, visited, nums); + return result; + } + + private void helper(List> result, + List list, + boolean[] visited, + int[] nums) { + if (list.size() == nums.length) { + result.add(new ArrayList<>(list)); + return; + } + + for (int i = 0; i < nums.length; i++) { + if (visited[i]) { + continue; + } + list.add(nums[i]); + visited[i] = true; + helper(result, list, visited, nums); + visited[i] = false; + list.remove(list.size() - 1); + } + } +} +//leetcode submit region end(Prohibit modification and deletion) diff --git "a/week03/[47]\345\205\250\346\216\222\345\210\227 II.java" "b/week03/[47]\345\205\250\346\216\222\345\210\227 II.java" new file mode 100644 index 00000000..07d982ce --- /dev/null +++ "b/week03/[47]\345\205\250\346\216\222\345\210\227 II.java" @@ -0,0 +1,73 @@ +//给定一个可包含重复数字的序列 nums ,按任意顺序 返回所有不重复的全排列。 +// +// +// +// 示例 1: +// +// +//输入:nums = [1,1,2] +//输出: +//[[1,1,2], +// [1,2,1], +// [2,1,1]] +// +// +// 示例 2: +// +// +//输入:nums = [1,2,3] +//输出:[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]] +// +// +// +// +// 提示: +// +// +// 1 <= nums.length <= 8 +// -10 <= nums[i] <= 10 +// +// Related Topics 回溯算法 +// 👍 518 👎 0 + + +import java.util.ArrayList; + +//leetcode submit region begin(Prohibit modification and deletion) +class Solution { + public List> permuteUnique(int[] nums) { + List> result = new ArrayList<>(); + if (nums == null || nums.length == 0) { + return result; + } + Arrays.sort(nums); + List list = new ArrayList<>(); + boolean[] visited = new boolean[nums.length]; + helper(visited, list, result, nums); + return result; + } + + public void helper(boolean[] visited, + List list, + List> result, + int[] nums) { + if (list.size() == nums.length) { + result.add(new ArrayList<>(list)); + return; + } + for (int i = 0; i < nums.length; i++) { + if (visited[i]) { + continue; + } + if (i > 0 && nums[i] == nums[i - 1] && visited[i - 1]) { + continue; + } + list.add(nums[i]); + visited[i] = true; + helper(visited, list, result, nums); + visited[i] = false; + list.remove(list.size() - 1); + } + } +} +//leetcode submit region end(Prohibit modification and deletion) diff --git "a/week03/[77]\347\273\204\345\220\210.java" "b/week03/[77]\347\273\204\345\220\210.java" new file mode 100644 index 00000000..6be5c6a0 --- /dev/null +++ "b/week03/[77]\347\273\204\345\220\210.java" @@ -0,0 +1,39 @@ +//给定两个整数 n 和 k,返回 1 ... n 中所有可能的 k 个数的组合。 +// +// 示例: +// +// 输入: n = 4, k = 2 +//输出: +//[ +// [2,4], +// [3,4], +// [2,3], +// [1,2], +// [1,3], +// [1,4], +//] +// Related Topics 回溯算法 +// 👍 432 👎 0 + + +//leetcode submit region begin(Prohibit modification and deletion) +class Solution { + public static List> combine(int n, int k) { + List> combs = new ArrayList>(); + combine(combs, new ArrayList(), 1, n, k); + return combs; + } + + public static void combine(List> combs, List comb, int start, int n, int k) { + if(k==0) { + combs.add(new ArrayList(comb)); + return; + } + for(int i = start; i <= n; i++) { + comb.add(i); + combine(combs, comb, i + 1, n, k - 1); + comb.remove(comb.size() - 1); + } + } +} +//leetcode submit region end(Prohibit modification and deletion) diff --git "a/week04/[122]\344\271\260\345\215\226\350\202\241\347\245\250\347\232\204\346\234\200\344\275\263\346\227\266\346\234\272 II.java" "b/week04/[122]\344\271\260\345\215\226\350\202\241\347\245\250\347\232\204\346\234\200\344\275\263\346\227\266\346\234\272 II.java" new file mode 100644 index 00000000..4bb3ce5d --- /dev/null +++ "b/week04/[122]\344\271\260\345\215\226\350\202\241\347\245\250\347\232\204\346\234\200\344\275\263\346\227\266\346\234\272 II.java" @@ -0,0 +1,56 @@ +//给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格。 +// +// 设计一个算法来计算你所能获取的最大利润。你可以尽可能地完成更多的交易(多次买卖一支股票)。 +// +// 注意:你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。 +// +// +// +// 示例 1: +// +// 输入: [7,1,5,3,6,4] +//输出: 7 +//解释: 在第 2 天(股票价格 = 1)的时候买入,在第 3 天(股票价格 = 5)的时候卖出, 这笔交易所能获得利润 = 5-1 = 4 。 +//  随后,在第 4 天(股票价格 = 3)的时候买入,在第 5 天(股票价格 = 6)的时候卖出, 这笔交易所能获得利润 = 6-3 = 3 。 +// +// +// 示例 2: +// +// 输入: [1,2,3,4,5] +//输出: 4 +//解释: 在第 1 天(股票价格 = 1)的时候买入,在第 5 天 (股票价格 = 5)的时候卖出, 这笔交易所能获得利润 = 5-1 = 4 。 +//  注意你不能在第 1 天和第 2 天接连购买股票,之后再将它们卖出。 +//  因为这样属于同时参与了多笔交易,你必须在再次购买前出售掉之前的股票。 +// +// +// 示例 3: +// +// 输入: [7,6,4,3,1] +//输出: 0 +//解释: 在这种情况下, 没有交易完成, 所以最大利润为 0。 +// +// +// +// 提示: +// +// +// 1 <= prices.length <= 3 * 10 ^ 4 +// 0 <= prices[i] <= 10 ^ 4 +// +// Related Topics 贪心算法 数组 +// 👍 990 👎 0 + + +//leetcode submit region begin(Prohibit modification and deletion) +class Solution { + public int maxProfit(int[] prices) { + int profit = 0; + for (int i = 1; i < prices.length; i++) { + if (prices[i] > prices[i - 1]) { + profit += prices[i] - prices[i - 1]; + } + } + return profit; + } +} +//leetcode submit region end(Prohibit modification and deletion) diff --git "a/week04/[153]\345\257\273\346\211\276\346\227\213\350\275\254\346\216\222\345\272\217\346\225\260\347\273\204\344\270\255\347\232\204\346\234\200\345\260\217\345\200\274.java" "b/week04/[153]\345\257\273\346\211\276\346\227\213\350\275\254\346\216\222\345\272\217\346\225\260\347\273\204\344\270\255\347\232\204\346\234\200\345\260\217\345\200\274.java" new file mode 100644 index 00000000..cd4d7272 --- /dev/null +++ "b/week04/[153]\345\257\273\346\211\276\346\227\213\350\275\254\346\216\222\345\272\217\346\225\260\347\273\204\344\270\255\347\232\204\346\234\200\345\260\217\345\200\274.java" @@ -0,0 +1,67 @@ +//假设按照升序排序的数组在预先未知的某个点上进行了旋转。例如,数组 [0,1,2,4,5,6,7] 可能变为 [4,5,6,7,0,1,2] 。 +// +// 请找出其中最小的元素。 +// +// +// +// 示例 1: +// +// +//输入:nums = [3,4,5,1,2] +//输出:1 +// +// +// 示例 2: +// +// +//输入:nums = [4,5,6,7,0,1,2] +//输出:0 +// +// +// 示例 3: +// +// +//输入:nums = [1] +//输出:1 +// +// +// +// +// 提示: +// +// +// 1 <= nums.length <= 5000 +// -5000 <= nums[i] <= 5000 +// nums 中的所有整数都是 唯一 的 +// nums 原来是一个升序排序的数组,但在预先未知的某个点上进行了旋转 +// +// Related Topics 数组 二分查找 +// 👍 298 👎 0 + + +//leetcode submit region begin(Prohibit modification and deletion) +class Solution { + public int findMin(int[] nums) { + // 寻找 First position <= Last Number + if (nums == null || nums.length == 0) { + return -1; + } + int start = 0, end = nums.length - 1; + int target = nums[nums.length - 1]; + // 防止死循环,最后得到两个数,再判断一下是start还是end + while (start + 1 < end) { + // 防止溢出 + int mid = start + (end - start) / 2; + if (nums[mid] == target) { + end = mid; + } else if (nums[mid] < target) { + end = mid; + } else { + start = mid; + } + } + // 判断 + return Math.min(nums[start], nums[end]); + } +} +//leetcode submit region end(Prohibit modification and deletion) diff --git "a/week04/[200]\345\262\233\345\261\277\346\225\260\351\207\217.java" "b/week04/[200]\345\262\233\345\261\277\346\225\260\351\207\217.java" new file mode 100644 index 00000000..41f2c492 --- /dev/null +++ "b/week04/[200]\345\262\233\345\261\277\346\225\260\351\207\217.java" @@ -0,0 +1,71 @@ +//给你一个由 '1'(陆地)和 '0'(水)组成的的二维网格,请你计算网格中岛屿的数量。 +// +// 岛屿总是被水包围,并且每座岛屿只能由水平方向或竖直方向上相邻的陆地连接形成。 +// +// 此外,你可以假设该网格的四条边均被水包围。 +// +// +// +// 示例 1: +// +// 输入: +//[ +//['1','1','1','1','0'], +//['1','1','0','1','0'], +//['1','1','0','0','0'], +//['0','0','0','0','0'] +//] +//输出: 1 +// +// +// 示例 2: +// +// 输入: +//[ +//['1','1','0','0','0'], +//['1','1','0','0','0'], +//['0','0','1','0','0'], +//['0','0','0','1','1'] +//] +//输出: 3 +//解释: 每座岛屿只能由水平和/或竖直方向上相邻的陆地连接而成。 +// +// Related Topics 深度优先搜索 广度优先搜索 并查集 +// 👍 785 👎 0 + + +//leetcode submit region begin(Prohibit modification and deletion) + + + +class Solution { + public int numIslands(char[][] grid) { + if (grid == null || grid.length == 0 || grid[0].length == 0) { + return 0; + } + int m = grid.length; + int n = grid[0].length; + int count = 0; + for (int i = 0; i < m; i++) { + for (int j = 0; j < n; j++) { + if (grid[i][j] == '1') { + count++; + dfs(grid, i, j, m, n); + } + } + } + return count; + } + + private void dfs(char[][] grid, int i, int j, int m, int n) { + if (i < 0 || i >= m || j < 0 || j >= n || grid[i][j] == '0') { + return; + } + grid[i][j] = '0'; + dfs(grid, i + 1, j, m, n); + dfs(grid, i - 1, j, m, n); + dfs(grid, i, j + 1, m, n); + dfs(grid, i, j - 1, m, n); + } +} +//leetcode submit region end(Prohibit modification and deletion) diff --git "a/week04/[33]\346\220\234\347\264\242\346\227\213\350\275\254\346\216\222\345\272\217\346\225\260\347\273\204.java" "b/week04/[33]\346\220\234\347\264\242\346\227\213\350\275\254\346\216\222\345\272\217\346\225\260\347\273\204.java" new file mode 100644 index 00000000..8d0f7988 --- /dev/null +++ "b/week04/[33]\346\220\234\347\264\242\346\227\213\350\275\254\346\216\222\345\272\217\346\225\260\347\273\204.java" @@ -0,0 +1,82 @@ +//给你一个整数数组 nums ,和一个整数 target 。 +// +// 该整数数组原本是按升序排列,但输入时在预先未知的某个点上进行了旋转。(例如,数组 [0,1,2,4,5,6,7] 可能变为 [4,5,6,7,0,1,2] +// )。 +// +// 请你在数组中搜索 target ,如果数组中存在这个目标值,则返回它的索引,否则返回 -1 。 +// +// +// 示例 1: +// +// +//输入:nums = [4,5,6,7,0,1,2], target = 0 +//输出:4 +// +// +// 示例 2: +// +// +//输入:nums = [4,5,6,7,0,1,2], target = 3 +//输出:-1 +// +// 示例 3: +// +// +//输入:nums = [1], target = 0 +//输出:-1 +// +// +// +// +// 提示: +// +// +// 1 <= nums.length <= 5000 +// -10^4 <= nums[i] <= 10^4 +// nums 中的每个值都 独一无二 +// nums 肯定会在某个点上旋转 +// -10^4 <= target <= 10^4 +// +// Related Topics 数组 二分查找 +// 👍 1064 👎 0 + + +//leetcode submit region begin(Prohibit modification and deletion) +class Solution { + public int search(int[] nums, int target) { + if (nums == null || nums.length == 0) { + return -1; + } + int start = 0, end = nums.length - 1; + // 防止死循环,最后得到两个数,再判断一下是start还是end + while (start + 1 < end) { + // 防止溢出 + int mid = start + (end - start) / 2; + if (nums[mid] == target) { + return mid; + } + if (nums[mid] > nums[start]) { + if (nums[start] <= target && target < nums[mid]) { + end = mid; + } else { + start = mid; + } + } else { + if (nums[mid] < target && target <= nums[end]) { + start = mid; + } else { + end = mid; + } + } + } + // 判断 + if (nums[start] == target) { + return start; + } + if (nums[end] == target) { + return end; + } + return -1; + } +} +//leetcode submit region end(Prohibit modification and deletion) diff --git "a/week04/[455]\345\210\206\345\217\221\351\245\274\345\271\262.java" "b/week04/[455]\345\210\206\345\217\221\351\245\274\345\271\262.java" new file mode 100644 index 00000000..7b2ee1ed --- /dev/null +++ "b/week04/[455]\345\210\206\345\217\221\351\245\274\345\271\262.java" @@ -0,0 +1,56 @@ +//假设你是一位很棒的家长,想要给你的孩子们一些小饼干。但是,每个孩子最多只能给一块饼干。 +// +// 对每个孩子 i,都有一个胃口值 g[i],这是能让孩子们满足胃口的饼干的最小尺寸;并且每块饼干 j,都有一个尺寸 s[j] 。如果 s[j] >= g[i +//],我们可以将这个饼干 j 分配给孩子 i ,这个孩子会得到满足。你的目标是尽可能满足越多数量的孩子,并输出这个最大数值。 +// +// +// 示例 1: +// +// +//输入: g = [1,2,3], s = [1,1] +//输出: 1 +//解释: +//你有三个孩子和两块小饼干,3个孩子的胃口值分别是:1,2,3。 +//虽然你有两块小饼干,由于他们的尺寸都是1,你只能让胃口值是1的孩子满足。 +//所以你应该输出1。 +// +// +// 示例 2: +// +// +//输入: g = [1,2], s = [1,2,3] +//输出: 2 +//解释: +//你有两个孩子和三块小饼干,2个孩子的胃口值分别是1,2。 +//你拥有的饼干数量和尺寸都足以让所有孩子满足。 +//所以你应该输出2. +// +// +// +// +// 提示: +// +// +// 1 <= g.length <= 3 * 104 +// 0 <= s.length <= 3 * 104 +// 1 <= g[i], s[j] <= 231 - 1 +// +// Related Topics 贪心算法 +// 👍 216 👎 0 + + +//leetcode submit region begin(Prohibit modification and deletion) +class Solution { + public int findContentChildren(int[] g, int[] s) { + Arrays.sort(g); + Arrays.sort(s); + int i = 0; + for (int j = 0; i < g.length && j < s.length; j++) { + if (g[i] <= s[j]) { + i++; + } + } + return i; + } +} +//leetcode submit region end(Prohibit modification and deletion) diff --git "a/week04/[55]\350\267\263\350\267\203\346\270\270\346\210\217.java" "b/week04/[55]\350\267\263\350\267\203\346\270\270\346\210\217.java" new file mode 100644 index 00000000..da9b1723 --- /dev/null +++ "b/week04/[55]\350\267\263\350\267\203\346\270\270\346\210\217.java" @@ -0,0 +1,38 @@ +//给定一个非负整数数组,你最初位于数组的第一个位置。 +// +// 数组中的每个元素代表你在该位置可以跳跃的最大长度。 +// +// 判断你是否能够到达最后一个位置。 +// +// 示例 1: +// +// 输入: [2,3,1,1,4] +//输出: true +//解释: 我们可以先跳 1 步,从位置 0 到达 位置 1, 然后再从位置 1 跳 3 步到达最后一个位置。 +// +// +// 示例 2: +// +// 输入: [3,2,1,0,4] +//输出: false +//解释: 无论怎样,你总会到达索引为 3 的位置。但该位置的最大跳跃长度是 0 , 所以你永远不可能到达最后一个位置。 +// +// Related Topics 贪心算法 数组 +// 👍 921 👎 0 + + +//leetcode submit region begin(Prohibit modification and deletion) +class Solution { + public boolean canJump(int[] nums) { + int max = 0; + for (int i = 0; i < nums.length; i++) { + // 跳不到 + if (max < i) { + return false; + } + max = Math.max(max, i + nums[i]); + } + return true; + } +} +//leetcode submit region end(Prohibit modification and deletion) diff --git "a/week04/[704]\344\272\214\345\210\206\346\237\245\346\211\276.java" "b/week04/[704]\344\272\214\345\210\206\346\237\245\346\211\276.java" new file mode 100644 index 00000000..ecb837a4 --- /dev/null +++ "b/week04/[704]\344\272\214\345\210\206\346\237\245\346\211\276.java" @@ -0,0 +1,61 @@ +//给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target ,写一个函数搜索 nums 中的 target,如果目标值存在返回下标,否 +//则返回 -1。 +// +// +//示例 1: +// +// 输入: nums = [-1,0,3,5,9,12], target = 9 +//输出: 4 +//解释: 9 出现在 nums 中并且下标为 4 +// +// +// 示例 2: +// +// 输入: nums = [-1,0,3,5,9,12], target = 2 +//输出: -1 +//解释: 2 不存在 nums 中因此返回 -1 +// +// +// +// +// 提示: +// +// +// 你可以假设 nums 中的所有元素是不重复的。 +// n 将在 [1, 10000]之间。 +// nums 的每个元素都将在 [-9999, 9999]之间。 +// +// Related Topics 二分查找 +// 👍 172 👎 0 + + +//leetcode submit region begin(Prohibit modification and deletion) +class Solution { + public int search(int[] nums, int target) { + if (nums == null || nums.length == 0) { + return -1; + } + int start = 0, end = nums.length - 1; + // 防止死循环,最后得到两个数,再判断一下是start还是end + while (start + 1 < end) { + // 防止溢出 + int mid = start + (end - start) / 2; + if (nums[mid] == target) { + end = mid; + } else if (nums[mid] < target) { + start = mid; + } else { + end = mid; + } + } + // 判断 + if (nums[start] == target) { + return start; + } + if (nums[end] == target) { + return end; + } + return -1; + } +} +//leetcode submit region end(Prohibit modification and deletion) diff --git "a/week04/[74]\346\220\234\347\264\242\344\272\214\347\273\264\347\237\251\351\230\265.java" "b/week04/[74]\346\220\234\347\264\242\344\272\214\347\273\264\347\237\251\351\230\265.java" new file mode 100644 index 00000000..d577f9fc --- /dev/null +++ "b/week04/[74]\346\220\234\347\264\242\344\272\214\347\273\264\347\237\251\351\230\265.java" @@ -0,0 +1,87 @@ +//编写一个高效的算法来判断 m x n 矩阵中,是否存在一个目标值。该矩阵具有如下特性: +// +// +// 每行中的整数从左到右按升序排列。 +// 每行的第一个整数大于前一行的最后一个整数。 +// +// +// +// +// 示例 1: +// +// +//输入:matrix = [[1,3,5,7],[10,11,16,20],[23,30,34,50]], target = 3 +//输出:true +// +// +// 示例 2: +// +// +//输入:matrix = [[1,3,5,7],[10,11,16,20],[23,30,34,50]], target = 13 +//输出:false +// +// +// 示例 3: +// +// +//输入:matrix = [], target = 0 +//输出:false +// +// +// +// +// 提示: +// +// +// m == matrix.length +// n == matrix[i].length +// 0 <= m, n <= 100 +// -104 <= matrix[i][j], target <= 104 +// +// Related Topics 数组 二分查找 +// 👍 274 👎 0 + + +//leetcode submit region begin(Prohibit modification and deletion) +class Solution { + public boolean searchMatrix(int[][] matrix, int target) { + if (matrix == null || matrix.length == 0 || matrix[0].length == 0) { + return false; + } + int start = 0, end = matrix.length - 1; + // 防止死循环,最后得到两个数,再判断一下是start还是end + while (start + 1 < end) { + // 防止溢出 + int mid = start + (end - start) / 2; + if (matrix[mid][0] == target) { + return true; + } else if (matrix[mid][0] < target) { + start = mid; + } else { + end = mid; + } + } + + int index; + if (matrix[end][0] <= target) { + index = end; + } else { + index = start; + } + start = 0; + end = matrix[0].length - 1; + while (start + 1 < end) { + // 防止溢出 + int mid = start + (end - start) / 2; + if (matrix[index][mid] == target) { + return true; + } else if (matrix[index][mid] < target) { + start = mid; + } else { + end = mid; + } + } + return matrix[index][start] == target || matrix[index][end] == target; + } +} +//leetcode submit region end(Prohibit modification and deletion) diff --git "a/week04/[860]\346\237\240\346\252\254\346\260\264\346\211\276\351\233\266.java" "b/week04/[860]\346\237\240\346\252\254\346\260\264\346\211\276\351\233\266.java" new file mode 100644 index 00000000..7469ddab --- /dev/null +++ "b/week04/[860]\346\237\240\346\252\254\346\260\264\346\211\276\351\233\266.java" @@ -0,0 +1,84 @@ +//在柠檬水摊上,每一杯柠檬水的售价为 5 美元。 +// +// 顾客排队购买你的产品,(按账单 bills 支付的顺序)一次购买一杯。 +// +// 每位顾客只买一杯柠檬水,然后向你付 5 美元、10 美元或 20 美元。你必须给每个顾客正确找零,也就是说净交易是每位顾客向你支付 5 美元。 +// +// 注意,一开始你手头没有任何零钱。 +// +// 如果你能给每位顾客正确找零,返回 true ,否则返回 false 。 +// +// 示例 1: +// +// 输入:[5,5,5,10,20] +//输出:true +//解释: +//前 3 位顾客那里,我们按顺序收取 3 张 5 美元的钞票。 +//第 4 位顾客那里,我们收取一张 10 美元的钞票,并返还 5 美元。 +//第 5 位顾客那里,我们找还一张 10 美元的钞票和一张 5 美元的钞票。 +//由于所有客户都得到了正确的找零,所以我们输出 true。 +// +// +// 示例 2: +// +// 输入:[5,5,10] +//输出:true +// +// +// 示例 3: +// +// 输入:[10,10] +//输出:false +// +// +// 示例 4: +// +// 输入:[5,5,10,10,20] +//输出:false +//解释: +//前 2 位顾客那里,我们按顺序收取 2 张 5 美元的钞票。 +//对于接下来的 2 位顾客,我们收取一张 10 美元的钞票,然后返还 5 美元。 +//对于最后一位顾客,我们无法退回 15 美元,因为我们现在只有两张 10 美元的钞票。 +//由于不是每位顾客都得到了正确的找零,所以答案是 false。 +// +// +// +// +// 提示: +// +// +// 0 <= bills.length <= 10000 +// bills[i] 不是 5 就是 10 或是 20 +// +// Related Topics 贪心算法 +// 👍 135 👎 0 + + +//leetcode submit region begin(Prohibit modification and deletion) +class Solution { + public boolean lemonadeChange(int[] bills) { + int five = 0, ten = 0; + for (int bill : bills) { + if (bill == 5) { + five++; + } + if (bill == 10) { + ten++; + five--; + } + if (bill == 20) { + if (ten > 0) { + ten--; + five--; + } else { + five -= 3; + } + } + if (five < 0) { + return false; + } + } + return true; + } +} +//leetcode submit region end(Prohibit modification and deletion) diff --git "a/week04/[874]\346\250\241\346\213\237\350\241\214\350\265\260\346\234\272\345\231\250\344\272\272.java" "b/week04/[874]\346\250\241\346\213\237\350\241\214\350\265\260\346\234\272\345\231\250\344\272\272.java" new file mode 100644 index 00000000..9c4e61c7 --- /dev/null +++ "b/week04/[874]\346\250\241\346\213\237\350\241\214\350\265\260\346\234\272\345\231\250\344\272\272.java" @@ -0,0 +1,90 @@ +//机器人在一个无限大小的网格上行走,从点 (0, 0) 处开始出发,面向北方。该机器人可以接收以下三种类型的命令: +// +// +// -2:向左转 90 度 +// -1:向右转 90 度 +// 1 <= x <= 9:向前移动 x 个单位长度 +// +// +// 在网格上有一些格子被视为障碍物。 +// +// 第 i 个障碍物位于网格点 (obstacles[i][0], obstacles[i][1]) +// +// 机器人无法走到障碍物上,它将会停留在障碍物的前一个网格方块上,但仍然可以继续该路线的其余部分。 +// +// 返回从原点到机器人所有经过的路径点(坐标为整数)的最大欧式距离的平方。 +// +// +// +// 示例 1: +// +// 输入: commands = [4,-1,3], obstacles = [] +//输出: 25 +//解释: 机器人将会到达 (3, 4) +// +// +// 示例 2: +// +// 输入: commands = [4,-1,4,-2,4], obstacles = [[2,4]] +//输出: 65 +//解释: 机器人在左转走到 (1, 8) 之前将被困在 (1, 4) 处 +// +// +// +// +// 提示: +// +// +// 0 <= commands.length <= 10000 +// 0 <= obstacles.length <= 10000 +// -30000 <= obstacle[i][0] <= 30000 +// -30000 <= obstacle[i][1] <= 30000 +// 答案保证小于 2 ^ 31 +// +// Related Topics 贪心算法 +// 👍 112 👎 0 + + +import java.util.HashSet; + +//leetcode submit region begin(Prohibit modification and deletion) +class Solution { + public int robotSim(int[] commands, int[][] obstacles) { +// W +// S -|- N +// E +// North, direction = 0, directions[direction] = {0, 1} +// East, direction = 1, directions[direction] = {1, 0} +// South, direction = 2, directions[direction] = {0, -1} +// West, direction = 3, directions[direction] = {-1, 0} +// +// direction will increase by one when we turn right, +// and will decrease by one (or increase by three) when we turn left. + int[][] directions = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}}; + Set obstaclesSet = new HashSet<>(); + for (int[] obstacle : obstacles) { + obstaclesSet.add(obstacle[0] + " " + obstacle[1]); + } + + int x = 0, y = 0, d = 0, maxDistSquare = 0; + for (int i = 0; i < commands.length; i++) { + if (commands[i] == -2) { + // turn left + d = (d + 3) % 4; + } else if (commands[i] == -1) { + d = (d + 1) % 4; + } else { + int step = 0; + while (step < commands[i] && + !obstaclesSet.contains((x + directions[d][0]) + " " + (y + directions[d][1]))) { + x += directions[d][0]; + y += directions[d][1]; + step++; + } + } + maxDistSquare = Math.max(maxDistSquare, x * x + y * y); + } + return maxDistSquare; + } +} +//leetcode submit region end(Prohibit modification and deletion) diff --git "a/week06/[221]\346\234\200\345\244\247\346\255\243\346\226\271\345\275\242.java" "b/week06/[221]\346\234\200\345\244\247\346\255\243\346\226\271\345\275\242.java" new file mode 100644 index 00000000..ce0503a2 --- /dev/null +++ "b/week06/[221]\346\234\200\345\244\247\346\255\243\346\226\271\345\275\242.java" @@ -0,0 +1,47 @@ +//在一个由 '0' 和 '1' 组成的二维矩阵内,找到只包含 '1' 的最大正方形,并返回其面积。 +// +// +// +// 示例: +// +// +//输入: +//matrix = [["1","0","1","0","0"], +// ["1","0","1","1","1"], +// ["1","1","1","1","1"], +// ["1","0","0","1","0"]] +// +//输出:4 +// Related Topics 动态规划 +// 👍 620 👎 0 + + +//leetcode submit region begin(Prohibit modification and deletion) +class Solution { + public int maximalSquare(char[][] matrix) { + if (matrix == null || matrix.length == 0 || matrix[0].length == 0) { + return 0; + } + int m = matrix.length, n = matrix[0].length; + int[][] dp = new int[m][n]; + int max = 0; + for (int i = 0; i < m; i++) { + dp[i][0] = matrix[i][0] - '0'; + max = Math.max(max, dp[i][0]); + } + for (int i = 0; i < n; i++) { + dp[0][i] = matrix[0][i] - '0'; + max = Math.max(max, dp[0][i]); + } + for (int i = 1; i < m; i++) { + for (int j = 1; j < n; j++) { + if (matrix[i][j] == '1') { + dp[i][j] = Math.min(Math.min(dp[i - 1][j], dp[i][j - 1]), dp[i - 1][j - 1]) + 1; + max = Math.max(max, dp[i][j]); + } + } + } + return max * max; + } +} +//leetcode submit region end(Prohibit modification and deletion) diff --git "a/week06/[64]\346\234\200\345\260\217\350\267\257\345\276\204\345\222\214.java" "b/week06/[64]\346\234\200\345\260\217\350\267\257\345\276\204\345\222\214.java" new file mode 100644 index 00000000..2c3a71c0 --- /dev/null +++ "b/week06/[64]\346\234\200\345\260\217\350\267\257\345\276\204\345\222\214.java" @@ -0,0 +1,59 @@ +//给定一个包含非负整数的 m x n 网格 grid ,请找出一条从左上角到右下角的路径,使得路径上的数字总和为最小。 +// +// 说明:每次只能向下或者向右移动一步。 +// +// +// +// 示例 1: +// +// +//输入:grid = [[1,3,1],[1,5,1],[4,2,1]] +//输出:7 +//解释:因为路径 1→3→1→1→1 的总和最小。 +// +// +// 示例 2: +// +// +//输入:grid = [[1,2,3],[4,5,6]] +//输出:12 +// +// +// +// +// 提示: +// +// +// m == grid.length +// n == grid[i].length +// 1 <= m, n <= 200 +// 0 <= grid[i][j] <= 100 +// +// Related Topics 数组 动态规划 +// 👍 716 👎 0 + + +//leetcode submit region begin(Prohibit modification and deletion) +class Solution { + public int minPathSum(int[][] grid) { + if (grid == null || grid.length == 0 || grid[0].length == 0) { + return 0; + } + int m = grid.length, n = grid[0].length; + int[][] dp = new int[m][n]; + dp[0][0] = grid[0][0]; + for (int i = 1; i < m; i++) { + dp[i][0] = dp[i - 1][0] + grid[i][0]; + } + for (int i = 1; i < n; i++) { + dp[0][i] = dp[0][i - 1] + grid[0][i]; + } + for (int i = 1; i < m; i++) { + for (int j = 1; j < n; j++) { + dp[i][j] = Math.min(dp[i - 1][j], dp[i][j - 1]) + grid[i][j]; + } + } + return dp[m - 1][n - 1]; + } +} +//leetcode submit region end(Prohibit modification and deletion) diff --git "a/week07/[200]\345\262\233\345\261\277\346\225\260\351\207\217.java" "b/week07/[200]\345\262\233\345\261\277\346\225\260\351\207\217.java" new file mode 100644 index 00000000..41f2c492 --- /dev/null +++ "b/week07/[200]\345\262\233\345\261\277\346\225\260\351\207\217.java" @@ -0,0 +1,71 @@ +//给你一个由 '1'(陆地)和 '0'(水)组成的的二维网格,请你计算网格中岛屿的数量。 +// +// 岛屿总是被水包围,并且每座岛屿只能由水平方向或竖直方向上相邻的陆地连接形成。 +// +// 此外,你可以假设该网格的四条边均被水包围。 +// +// +// +// 示例 1: +// +// 输入: +//[ +//['1','1','1','1','0'], +//['1','1','0','1','0'], +//['1','1','0','0','0'], +//['0','0','0','0','0'] +//] +//输出: 1 +// +// +// 示例 2: +// +// 输入: +//[ +//['1','1','0','0','0'], +//['1','1','0','0','0'], +//['0','0','1','0','0'], +//['0','0','0','1','1'] +//] +//输出: 3 +//解释: 每座岛屿只能由水平和/或竖直方向上相邻的陆地连接而成。 +// +// Related Topics 深度优先搜索 广度优先搜索 并查集 +// 👍 785 👎 0 + + +//leetcode submit region begin(Prohibit modification and deletion) + + + +class Solution { + public int numIslands(char[][] grid) { + if (grid == null || grid.length == 0 || grid[0].length == 0) { + return 0; + } + int m = grid.length; + int n = grid[0].length; + int count = 0; + for (int i = 0; i < m; i++) { + for (int j = 0; j < n; j++) { + if (grid[i][j] == '1') { + count++; + dfs(grid, i, j, m, n); + } + } + } + return count; + } + + private void dfs(char[][] grid, int i, int j, int m, int n) { + if (i < 0 || i >= m || j < 0 || j >= n || grid[i][j] == '0') { + return; + } + grid[i][j] = '0'; + dfs(grid, i + 1, j, m, n); + dfs(grid, i - 1, j, m, n); + dfs(grid, i, j + 1, m, n); + dfs(grid, i, j - 1, m, n); + } +} +//leetcode submit region end(Prohibit modification and deletion) diff --git "a/week07/[22]\346\213\254\345\217\267\347\224\237\346\210\220.java" "b/week07/[22]\346\213\254\345\217\267\347\224\237\346\210\220.java" new file mode 100644 index 00000000..ab6a4742 --- /dev/null +++ "b/week07/[22]\346\213\254\345\217\267\347\224\237\346\210\220.java" @@ -0,0 +1,44 @@ +//数字 n 代表生成括号的对数,请你设计一个函数,用于能够生成所有可能的并且 有效的 括号组合。 +// +// +// +// 示例: +// +// 输入:n = 3 +//输出:[ +// "((()))", +// "(()())", +// "(())()", +// "()(())", +// "()()()" +// ] +// +// Related Topics 字符串 回溯算法 +// 👍 1394 👎 0 + + +import java.util.ArrayList; +import java.util.List; + +//leetcode submit region begin(Prohibit modification and deletion) +class Solution { + public List generateParenthesis(int n) { + List res = new ArrayList<>(); + backtrace(res, 0, 0, n, ""); + return res; + } + + private void backtrace(List res, int left, int right, int max, String s) { + if (left == max && right == max) { + res.add(s); + return; + } + if (left < max) { + backtrace(res, left + 1, right, max, s + "("); + } + if (right < left) { + backtrace(res, left, right + 1, max, s + ")"); + } + } +} +//leetcode submit region end(Prohibit modification and deletion) diff --git "a/week08/[191]\344\275\2151\347\232\204\344\270\252\346\225\260.java" "b/week08/[191]\344\275\2151\347\232\204\344\270\252\346\225\260.java" new file mode 100644 index 00000000..7306f42f --- /dev/null +++ "b/week08/[191]\344\275\2151\347\232\204\344\270\252\346\225\260.java" @@ -0,0 +1,74 @@ +//编写一个函数,输入是一个无符号整数(以二进制串的形式),返回其二进制表达式中数字位数为 '1' 的个数(也被称为汉明重量)。 +// +// +// +// 提示: +// +// +// 请注意,在某些语言(如 Java)中,没有无符号整数类型。在这种情况下,输入和输出都将被指定为有符号整数类型,并且不应影响您的实现,因为无论整数是有符号的 +//还是无符号的,其内部的二进制表示形式都是相同的。 +// 在 Java 中,编译器使用二进制补码记法来表示有符号整数。因此,在上面的 示例 3 中,输入表示有符号整数 -3。 +// +// +// +// +// 进阶: +// +// +// 如果多次调用这个函数,你将如何优化你的算法? +// +// +// +// +// 示例 1: +// +// +//输入:00000000000000000000000000001011 +//输出:3 +//解释:输入的二进制串 00000000000000000000000000001011 中,共有三位为 '1'。 +// +// +// 示例 2: +// +// +//输入:00000000000000000000000010000000 +//输出:1 +//解释:输入的二进制串 00000000000000000000000010000000 中,共有一位为 '1'。 +// +// +// 示例 3: +// +// +//输入:11111111111111111111111111111101 +//输出:31 +//解释:输入的二进制串 11111111111111111111111111111101 中,共有 31 位为 '1'。 +// +// +// +// 提示: +// +// +// 输入必须是长度为 32 的 二进制串 。 +// +// +// +// +// +// +// Related Topics 位运算 +// 👍 241 👎 0 + + +//leetcode submit region begin(Prohibit modification and deletion) +public class Solution { + // you need to treat n as an unsigned value + public int hammingWeight(int n) { + int count = 0; + while (n != 0) { + count += n & 1; + n = n >>> 1; + } + return count; + } +} +//leetcode submit region end(Prohibit modification and deletion) diff --git "a/week08/[231]2\347\232\204\345\271\202.java" "b/week08/[231]2\347\232\204\345\271\202.java" new file mode 100644 index 00000000..a14fdcdf --- /dev/null +++ "b/week08/[231]2\347\232\204\345\271\202.java" @@ -0,0 +1,29 @@ +//给定一个整数,编写一个函数来判断它是否是 2 的幂次方。 +// +// 示例 1: +// +// 输入: 1 +//输出: true +//解释: 20 = 1 +// +// 示例 2: +// +// 输入: 16 +//输出: true +//解释: 24 = 16 +// +// 示例 3: +// +// 输入: 218 +//输出: false +// Related Topics 位运算 数学 +// 👍 265 👎 0 + + +//leetcode submit region begin(Prohibit modification and deletion) +class Solution { + public boolean isPowerOfTwo(int n) { + return n > 0 && Integer.bitCount(n) == 1; + } +} +//leetcode submit region end(Prohibit modification and deletion) diff --git "a/week09/[300]\346\234\200\351\225\277\344\270\212\345\215\207\345\255\220\345\272\217\345\210\227.java" "b/week09/[300]\346\234\200\351\225\277\344\270\212\345\215\207\345\255\220\345\272\217\345\210\227.java" new file mode 100644 index 00000000..d514193f --- /dev/null +++ "b/week09/[300]\346\234\200\351\225\277\344\270\212\345\215\207\345\255\220\345\272\217\345\210\227.java" @@ -0,0 +1,41 @@ +//给定一个无序的整数数组,找到其中最长上升子序列的长度。 +// +// 示例: +// +// 输入: [10,9,2,5,3,7,101,18] +//输出: 4 +//解释: 最长的上升子序列是 [2,3,7,101],它的长度是 4。 +// +// 说明: +// +// +// 可能会有多种最长上升子序列的组合,你只需要输出对应的长度即可。 +// 你算法的时间复杂度应该为 O(n2) 。 +// +// +// 进阶: 你能将算法的时间复杂度降低到 O(n log n) 吗? +// Related Topics 二分查找 动态规划 +// 👍 1157 👎 0 + + +//leetcode submit region begin(Prohibit modification and deletion) +class Solution { + public int lengthOfLIS(int[] nums) { + if (nums == null || nums.length == 0) { + return 0; + } + int[] dp = new int[nums.length]; + int ans = 1; + for (int i = 0; i < nums.length; i++) { + dp[i] = 1; + for (int j = 0; j < i; j++) { + if (nums[i] > nums[j]) { + dp[i] = Math.max(dp[i], dp[j] + 1); + } + } + ans = Math.max(ans, dp[i]); + } + return ans; + } +} +//leetcode submit region end(Prohibit modification and deletion) diff --git "a/week09/[387]\345\255\227\347\254\246\344\270\262\344\270\255\347\232\204\347\254\254\344\270\200\344\270\252\345\224\257\344\270\200\345\255\227\347\254\246.java" "b/week09/[387]\345\255\227\347\254\246\344\270\262\344\270\255\347\232\204\347\254\254\344\270\200\344\270\252\345\224\257\344\270\200\345\255\227\347\254\246.java" new file mode 100644 index 00000000..e379d462 --- /dev/null +++ "b/week09/[387]\345\255\227\347\254\246\344\270\262\344\270\255\347\232\204\347\254\254\344\270\200\344\270\252\345\224\257\344\270\200\345\255\227\347\254\246.java" @@ -0,0 +1,40 @@ +//给定一个字符串,找到它的第一个不重复的字符,并返回它的索引。如果不存在,则返回 -1。 +// +// +// +// 示例: +// +// s = "leetcode" +//返回 0 +// +//s = "loveleetcode" +//返回 2 +// +// +// +// +// 提示:你可以假定该字符串只包含小写字母。 +// Related Topics 哈希表 字符串 +// 👍 298 👎 0 + + +//leetcode submit region begin(Prohibit modification and deletion) +class Solution { + public int firstUniqChar(String s) { + if (s == null || s.length() == 0) { + return -1; + } + int[] arr = new int[27]; + for (char c : s.toCharArray()) { + arr[c - 'a']++; + } + for (int i = 0; i < s.length(); i++) { + char c = s.charAt(i); + if (arr[c - 'a'] == 1) { + return i; + } + } + return -1; + } +} +//leetcode submit region end(Prohibit modification and deletion)