From bedf026cfa56fe3dd77d397eba16eb6db0cf364a Mon Sep 17 00:00:00 2001 From: qiyue Date: Sat, 4 Jan 2020 18:19:49 +0800 Subject: [PATCH 01/41] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...ndroid_support_appcompat_v7_23_4_0_aar.xml | 3 - ..._design_bottomappbar_28_0_0_alpha1_aar.xml | 3 - ...ign_bottomnavigation_28_0_0_alpha1_aar.xml | 3 - ..._support_design_chip_28_0_0_alpha1_aar.xml | 3 - ...esign_circularreveal_28_0_0_alpha1_aar.xml | 3 - ...port_design_internal_28_0_0_alpha1_aar.xml | 3 - ...support_design_theme_28_0_0_alpha1_aar.xml | 3 - ...esign_transformation_28_0_0_alpha1_aar.xml | 3 - ...upport_design_widget_28_0_0_alpha1_aar.xml | 3 - ..._android_support_support_v4_23_4_0_aar.xml | 3 - ...com_android_support_test_rules_0_5_aar.xml | 3 - ...om_android_support_test_runner_0_5_aar.xml | 3 - .idea/workspace.xml | 592 +++++++++--------- .../{base => leetcode}/ArrayTest.kt | 5 +- .../{base => leetcode}/LeetCode20.kt | 2 +- .../datastructure/leetcode/LeetCode230.kt | 120 ++++ .../datastructure/leetcode/LeetCode239.kt | 85 +++ .../{base => leetcode}/LeetCode242.kt | 2 +- .../{base => leetcode}/LeetCode25.kt | 4 +- .../datastructure/leetcode/LeetCode347.kt | 82 +++ .../datastructure/leetcode/LeetCode739.kt | 63 ++ .../com/wangpos/datastructure/leetcode/readme | 15 + 22 files changed, 670 insertions(+), 336 deletions(-) rename app/src/main/java/com/wangpos/datastructure/{base => leetcode}/ArrayTest.kt (92%) rename app/src/main/java/com/wangpos/datastructure/{base => leetcode}/LeetCode20.kt (97%) create mode 100644 app/src/main/java/com/wangpos/datastructure/leetcode/LeetCode230.kt create mode 100644 app/src/main/java/com/wangpos/datastructure/leetcode/LeetCode239.kt rename app/src/main/java/com/wangpos/datastructure/{base => leetcode}/LeetCode242.kt (94%) rename app/src/main/java/com/wangpos/datastructure/{base => leetcode}/LeetCode25.kt (94%) create mode 100644 app/src/main/java/com/wangpos/datastructure/leetcode/LeetCode347.kt create mode 100644 app/src/main/java/com/wangpos/datastructure/leetcode/LeetCode739.kt create mode 100644 app/src/main/java/com/wangpos/datastructure/leetcode/readme diff --git a/.idea/libraries/Gradle__com_android_support_appcompat_v7_23_4_0_aar.xml b/.idea/libraries/Gradle__com_android_support_appcompat_v7_23_4_0_aar.xml index 4fe18a6..f9f3377 100644 --- a/.idea/libraries/Gradle__com_android_support_appcompat_v7_23_4_0_aar.xml +++ b/.idea/libraries/Gradle__com_android_support_appcompat_v7_23_4_0_aar.xml @@ -1,8 +1,5 @@ - - - diff --git a/.idea/libraries/Gradle__com_android_support_design_bottomappbar_28_0_0_alpha1_aar.xml b/.idea/libraries/Gradle__com_android_support_design_bottomappbar_28_0_0_alpha1_aar.xml index f12471c..a44ce5f 100644 --- a/.idea/libraries/Gradle__com_android_support_design_bottomappbar_28_0_0_alpha1_aar.xml +++ b/.idea/libraries/Gradle__com_android_support_design_bottomappbar_28_0_0_alpha1_aar.xml @@ -1,8 +1,5 @@ - - - diff --git a/.idea/libraries/Gradle__com_android_support_design_bottomnavigation_28_0_0_alpha1_aar.xml b/.idea/libraries/Gradle__com_android_support_design_bottomnavigation_28_0_0_alpha1_aar.xml index 1c4f8e1..359e4dd 100644 --- a/.idea/libraries/Gradle__com_android_support_design_bottomnavigation_28_0_0_alpha1_aar.xml +++ b/.idea/libraries/Gradle__com_android_support_design_bottomnavigation_28_0_0_alpha1_aar.xml @@ -1,8 +1,5 @@ - - - diff --git a/.idea/libraries/Gradle__com_android_support_design_chip_28_0_0_alpha1_aar.xml b/.idea/libraries/Gradle__com_android_support_design_chip_28_0_0_alpha1_aar.xml index 3f1eac5..10fb32e 100644 --- a/.idea/libraries/Gradle__com_android_support_design_chip_28_0_0_alpha1_aar.xml +++ b/.idea/libraries/Gradle__com_android_support_design_chip_28_0_0_alpha1_aar.xml @@ -1,8 +1,5 @@ - - - diff --git a/.idea/libraries/Gradle__com_android_support_design_circularreveal_28_0_0_alpha1_aar.xml b/.idea/libraries/Gradle__com_android_support_design_circularreveal_28_0_0_alpha1_aar.xml index 24e44ee..3c99129 100644 --- a/.idea/libraries/Gradle__com_android_support_design_circularreveal_28_0_0_alpha1_aar.xml +++ b/.idea/libraries/Gradle__com_android_support_design_circularreveal_28_0_0_alpha1_aar.xml @@ -1,8 +1,5 @@ - - - diff --git a/.idea/libraries/Gradle__com_android_support_design_internal_28_0_0_alpha1_aar.xml b/.idea/libraries/Gradle__com_android_support_design_internal_28_0_0_alpha1_aar.xml index 0d56144..f484633 100644 --- a/.idea/libraries/Gradle__com_android_support_design_internal_28_0_0_alpha1_aar.xml +++ b/.idea/libraries/Gradle__com_android_support_design_internal_28_0_0_alpha1_aar.xml @@ -1,8 +1,5 @@ - - - diff --git a/.idea/libraries/Gradle__com_android_support_design_theme_28_0_0_alpha1_aar.xml b/.idea/libraries/Gradle__com_android_support_design_theme_28_0_0_alpha1_aar.xml index a216a1b..58d3369 100644 --- a/.idea/libraries/Gradle__com_android_support_design_theme_28_0_0_alpha1_aar.xml +++ b/.idea/libraries/Gradle__com_android_support_design_theme_28_0_0_alpha1_aar.xml @@ -1,8 +1,5 @@ - - - diff --git a/.idea/libraries/Gradle__com_android_support_design_transformation_28_0_0_alpha1_aar.xml b/.idea/libraries/Gradle__com_android_support_design_transformation_28_0_0_alpha1_aar.xml index bd5a375..e509623 100644 --- a/.idea/libraries/Gradle__com_android_support_design_transformation_28_0_0_alpha1_aar.xml +++ b/.idea/libraries/Gradle__com_android_support_design_transformation_28_0_0_alpha1_aar.xml @@ -1,8 +1,5 @@ - - - diff --git a/.idea/libraries/Gradle__com_android_support_design_widget_28_0_0_alpha1_aar.xml b/.idea/libraries/Gradle__com_android_support_design_widget_28_0_0_alpha1_aar.xml index d9b284a..5dfdcdb 100644 --- a/.idea/libraries/Gradle__com_android_support_design_widget_28_0_0_alpha1_aar.xml +++ b/.idea/libraries/Gradle__com_android_support_design_widget_28_0_0_alpha1_aar.xml @@ -1,8 +1,5 @@ - - - diff --git a/.idea/libraries/Gradle__com_android_support_support_v4_23_4_0_aar.xml b/.idea/libraries/Gradle__com_android_support_support_v4_23_4_0_aar.xml index 87e92a3..bf6b78d 100644 --- a/.idea/libraries/Gradle__com_android_support_support_v4_23_4_0_aar.xml +++ b/.idea/libraries/Gradle__com_android_support_support_v4_23_4_0_aar.xml @@ -1,8 +1,5 @@ - - - diff --git a/.idea/libraries/Gradle__com_android_support_test_rules_0_5_aar.xml b/.idea/libraries/Gradle__com_android_support_test_rules_0_5_aar.xml index 5b8abd2..e2388c0 100644 --- a/.idea/libraries/Gradle__com_android_support_test_rules_0_5_aar.xml +++ b/.idea/libraries/Gradle__com_android_support_test_rules_0_5_aar.xml @@ -1,8 +1,5 @@ - - - diff --git a/.idea/libraries/Gradle__com_android_support_test_runner_0_5_aar.xml b/.idea/libraries/Gradle__com_android_support_test_runner_0_5_aar.xml index 7b97cd0..0d52894 100644 --- a/.idea/libraries/Gradle__com_android_support_test_runner_0_5_aar.xml +++ b/.idea/libraries/Gradle__com_android_support_test_runner_0_5_aar.xml @@ -1,8 +1,5 @@ - - - diff --git a/.idea/workspace.xml b/.idea/workspace.xml index db2bdb4..5a00d85 100644 --- a/.idea/workspace.xml +++ b/.idea/workspace.xml @@ -13,94 +13,28 @@ - - - - - - - - - - - - - + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + - + - + - + - + - + - + - - - - - + + + + + - - - - - + + + + + @@ -4173,10 +4155,10 @@ - + - + @@ -4184,8 +4166,8 @@ - - + + @@ -4195,7 +4177,7 @@ - + @@ -4675,6 +4657,12 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -4954,16 +4880,6 @@ - - - - - - - - - - @@ -4971,13 +4887,6 @@ - - - - - - - @@ -5044,13 +4953,6 @@ - - - - - - - @@ -5058,16 +4960,6 @@ - - - - - - - - - - @@ -5126,8 +5018,108 @@ - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/java/com/wangpos/datastructure/leetcode/LeetCode1038.kt b/app/src/main/java/com/wangpos/datastructure/leetcode/LeetCode1038.kt new file mode 100644 index 0000000..52c09ab --- /dev/null +++ b/app/src/main/java/com/wangpos/datastructure/leetcode/LeetCode1038.kt @@ -0,0 +1,100 @@ +package com.wangpos.datastructure.leetcode + +import java.util.* + +/** + * 二叉查找树(英语:Binary Search Tree),也称为 二叉搜索树、有序二叉树(Ordered Binary Tree)或排序二叉树(Sorted Binary Tree),是指一棵空树或者具有下列性质的二叉树: + +若任意节点的左子树不空,则左子树上所有节点的值均小于它的根节点的值; +若任意节点的右子树不空,则右子树上所有节点的值均大于它的根节点的值; +任意节点的左、右子树也分别为二叉查找树; +没有键值相等的节点。 +二叉查找树相比于其他数据结构的优势在于查找、插入的时间复杂度较低。为 O(\log n)O(logn)。二叉查找树是基础性数据结构,用于构建更为抽象的数据结构,如集合、多重集、关联数组等。 + +二叉查找树的查找过程和次优二叉树类似,通常采取二叉链表作为二叉查找树的存储结构。中序遍历二叉查找树可得到一个关键字的有序序列,一个无序序列可以通过构造一棵二叉查找树变成一个有序序列,构造树的过程即为对无序序列进行查找的过程。每次插入的新的结点都是二叉查找树上新的叶子结点,在进行插入操作时,不必移动其它结点,只需改动某个结点的指针,由空变为非空即可。搜索、插入、删除的复杂度等于树高,期望 O(\log n)O(logn),最坏 O(n)O(n)(数列有序,树退化成线性表)。 + + + +虽然二叉查找树的最坏效率是 O(n)O(n),但它支持动态查询,且有很多改进版的二叉查找树可以使树高为 O(\log n)O(logn),从而将最坏效率降至 O(\log n)O(logn),如 AVL 树、红黑树等。 + + */ +fun main() { + + //右左根的遍历方式 + //记忆搜索 + + //不存在相等的元素 + val arrayNode = arrayOf(4, 1, 6, 0, 2, 5, 7, null, null, null, 3, null, null, null, 8) +// val arrayNode = arrayOf( 6, 5, 7, 8) + var head: TreeNode? = null + arrayNode.forEach { + if (it != null) { + if (head == null) { + head = TreeNode(it) + } else { + createBinearySearchTree(head!!, it!!) + } + } + } + //打出中序遍历结果判断访问是否正确 + head?.let { printNode(it) } + + println() + head?.let { modifyNode(it) } + println() + + + println() + head?.let { printNode(it) } + +} + +fun createBinearySearchTree(head: TreeNode, it: Int) { + + var next: TreeNode? = null + if (it > head.`val`) { + next = head.right + if (next == null) { + head.right = TreeNode(it) + return + } + } else { + next = head.left + if (next == null) { + head.left = TreeNode(it) + return + } + } + + createBinearySearchTree(next, it) + +} + +//中序遍历左跟右 +fun printNode(head: TreeNode) { + head.left?.let { printNode(it) } + print(" ${head.`val`} ") + head.right?.let { printNode(it) } +} + + + +var cacheTotal = 0 +//右 根 左 把每个节点和队列之前的计算和添加到队列, +fun modifyNode(root: TreeNode) { + root.right?.let { modifyNode(it) } + print(" ${root.`val`} ") + if (cacheTotal==0) { + cacheTotal = root.`val` + + } else { + cacheTotal += root.`val` + root.`val` = cacheTotal + } + root.left?.let { modifyNode(it) } +} + +class TreeNode(var `val`: Int) { + var left: TreeNode? = null + var right: TreeNode? = null +} diff --git a/app/src/main/java/com/wangpos/datastructure/leetcode/LeetCode1214.java b/app/src/main/java/com/wangpos/datastructure/leetcode/LeetCode1214.java new file mode 100644 index 0000000..65e3b74 --- /dev/null +++ b/app/src/main/java/com/wangpos/datastructure/leetcode/LeetCode1214.java @@ -0,0 +1,101 @@ +package com.wangpos.datastructure.leetcode; + +import java.util.Stack; + +public class LeetCode1214 { + + public boolean twoSumBSTs(TreeNode root1, TreeNode root2, int target) { + + Stack stack1 = new Stack<>(); + Stack stack2 = new Stack<>(); + searchRoot11(root1, stack1); + searchRoot22(root2, stack2); + int t = 0; + int small = stack1.pop(); + int large = stack2.pop(); + while (!stack1.empty() || !stack2.empty()) { + t = small + large; + if (t == target) { + return true; + } else if (t > target) { + // 取较小的 + if(!stack1.empty()) { + small = stack1.pop(); + }else{ + break; + } + } else { + // 取较大的 + if(!stack2.empty()) { + large = stack2.pop(); + }else{ + break; + } + } + } + return false; + } + + private void searchRoot11(TreeNode root1, Stack stack) { + if (root1 == null) { + return; + } + searchRoot11(root1.getLeft(), stack); + stack.add(root1.getVal()); + searchRoot11(root1.getRight(), stack); + } + + private void searchRoot22(TreeNode root1, Stack stack) { + + if (root1 == null) { + return; + } + searchRoot22(root1.getRight(), stack); + stack.add(root1.getVal()); + searchRoot22(root1.getLeft(), stack); + } +// +// fun twoSumBSTs2(root1: TreeNode?, root2: TreeNode?, target: Int): Boolean { +// +// val stack1 = Stack()//从小到大 top最大 +// val stack2 = Stack()//从大到小 +// searchRoot11(root1, stack1) +// searchRoot22(root2, stack2) +// var t = 0 +// var small = stack1.pop() +// var large = stack2.pop() +// while (stack1.isNotEmpty() && stack2.isNotEmpty()) { +// t = small + large +// println(small) +// println(large) +// if (t == target) { +// return true +// } else if (t > target) { +// // 取较小的 +// small = stack1.pop() +// } else { +// // 取较大的 +// large = stack2.pop() +// } +// } +// return false +// } +// +// fun searchRoot11(root1: TreeNode?, stack: Stack) { +// if (root1 == null) { +// return +// } +// searchRoot11(root1.left, stack) +// stack.add(root1.`val`) +// searchRoot11(root1.right, stack) +// } +// +// fun searchRoot22(root2: TreeNode?, stack: Stack) { +// if (root2 == null) { +// return +// } +// searchRoot22(root2.right, stack) +// stack.add(root2.`val`) +// searchRoot22(root2.left, stack) +// } +} diff --git a/app/src/main/java/com/wangpos/datastructure/leetcode/LeetCode1214.kt b/app/src/main/java/com/wangpos/datastructure/leetcode/LeetCode1214.kt new file mode 100644 index 0000000..8cbc305 --- /dev/null +++ b/app/src/main/java/com/wangpos/datastructure/leetcode/LeetCode1214.kt @@ -0,0 +1,138 @@ +package com.wangpos.datastructure.leetcode + +import java.util.* + +fun main() { + + val root1Array = arrayOf(0, -10, 10) + + val root2Array = arrayOf(5, 1, 7, 0, 2) + + val target = 18 + + var root1: TreeNode? = null + var root2: TreeNode? = null + root1Array.forEach { + if (it != null) { + if (root1 == null) { + root1 = TreeNode(it) + } else { + createBinearySearchTree(root1!!, it!!) + } + } + } + + root2Array.forEach { + if (it != null) { + if (root2 == null) { + root2 = TreeNode(it) + } else { + createBinearySearchTree(root2!!, it!!) + } + } + } + +// root1?.let { printNode(it) } +// println() +// root2?.let { printNode(it) } + +// val result = twoSumBSTs(root1, root2, target) + +// val result = twoSumBSTs2(root1, root2, target) + val result = LeetCode1214().twoSumBSTs(root1,root2,target); + println("结果:${result}") +} + +/** + * 这种双层嵌套效率比较低,中序遍历时间复杂度是O(n) 后面的查找属于也是中序遍历所以O(n*n) + * + */ +fun twoSumBSTs(root1: TreeNode?, root2: TreeNode?, target: Int): Boolean { + searchRoot1(root1, root2, target) + return searchResult +} + +fun searchRoot1(root1: TreeNode?, root2: TreeNode?, target: Int) { + + if (root1 == null || searchResult) { + return + } + searchRoot1(root1?.left, root2, target) + if (root1.`val` > target) { + return + } + searchRoot2(root2, target - root1.`val`) + searchRoot1(root1?.right, root2, target) +} + +var searchResult = false +fun searchRoot2(root2: TreeNode?, i: Int) { + if (root2 == null || searchResult) { + return + } + searchRoot2(root2.left, i) + if (root2.`val` == i) { + searchResult = true + return + } + if (root2.`val` > i) { + return + } + searchRoot2(root2.right, i) +} + +/** + * 将两个树进行中序遍历,和逆向中序,时间复杂度 O(n)*2 + * 然后放入两个栈中,得到两个一个从小到大,一个从大到小的 + * + * 然后遍历两个栈,如果相加之和小于t,就从最小的栈去继续找,反之从大的栈中找 + * + * + */ +fun twoSumBSTs2(root1: TreeNode?, root2: TreeNode?, target: Int): Boolean { + + val stack1 = Stack()//从小到大 top最大 + val stack2 = Stack()//从大到小 + searchRoot11(root1, stack1) + searchRoot22(root2, stack2) + var t = 0 + var small = stack1.pop() + var large = stack2.pop() + while (stack1.isNotEmpty() || stack2.isNotEmpty()) { + t = small + large + println(small) + println(large) + if (t == target) { + return true + } else if (t > target) { + // 取较小的 + if(stack1.isNotEmpty()) { + small = stack1.pop() + } + } else { + // 取较大的 + if(stack1.isNotEmpty()) { + large = stack2.pop() + } + } + } + return false +} + +fun searchRoot11(root1: TreeNode?, stack: Stack) { + if (root1 == null) { + return + } + searchRoot11(root1.left, stack) + stack.add(root1.`val`) + searchRoot11(root1.right, stack) +} + +fun searchRoot22(root2: TreeNode?, stack: Stack) { + if (root2 == null) { + return + } + searchRoot22(root2.right, stack) + stack.add(root2.`val`) + searchRoot22(root2.left, stack) +} \ No newline at end of file diff --git a/app/src/main/java/com/wangpos/datastructure/leetcode/LeetCode329.kt b/app/src/main/java/com/wangpos/datastructure/leetcode/LeetCode329.kt new file mode 100644 index 0000000..0ac9e55 --- /dev/null +++ b/app/src/main/java/com/wangpos/datastructure/leetcode/LeetCode329.kt @@ -0,0 +1,152 @@ +package com.wangpos.datastructure.leetcode + +/** + * 矩阵中最长增长路径 + * + * 记忆化: 对于大量重复调用的问题,缓存其结果。 + 动态规划要求按照拓扑顺序解决子问题。对于很多问题,拓扑顺序与自然秩序一致。而对于那些并非如此的问题,需要首先执行拓扑排序。因此,对于复杂拓扑问题(如本题),使用记忆化搜索通常是更容易更好的选择。 + + 想要让动态规划有效,如果问题 B 依赖于问题 A 的结果,就必须确保问题 A 比问题 B先计算。这样的依赖顺序对许多问题十分简单自然。如著名的斐波那契数列 + */ +fun main() { + + /** + * 通过二维数组定义方向 + * + * 比如当前的二维数组中元素为0,0;垂直整下的元素就需要第二位加一,也就是列加一,所以是0,1 + * 同理向上0,-1, 向左 -1,0,向右 1.0 + * + * + */ + + val matrix = arrayOf>(arrayOf(9, 9, 4), arrayOf(6, 6, 8), arrayOf(2, 2, 1)) + val result = longestIncreasingPath(matrix) + + println("结果:${result}") +} + +/** + * 采用深度优先搜索解决此题, + * + * 因为最坏时间是从第一列第一个个元素到第一列最后元素再到最后一行最后一个元素 + * + * 所以相当于第一次搜索 1分为二,第二次二分为4 所以时间复杂度2^n,注意这只是一个点的深度优先搜索,mn 个所以复杂度很高,具体为什么是2^(m+n)本人也没太仔细算 + * + * 时间复杂度是 O(2^(m+n)) + * + * 空间复杂度O(mn) + */ +fun longestIncreasingPath(matrix: Array>): Int { + + if (matrix.size == 0) return 0 + //几列 + m = matrix.size + //几行 + n = matrix[0].size + //最长路径 + var ans = 0 + for (i in 0 until m) { + for (j in 0 until n) { + //每个顶点做四个方向的深度优先搜索 + ans = Math.max(ans, dfs(matrix, i, j)); + } + } + + return ans +} + +/** + * 深度优先搜索 + */ +fun dfs(matrix: Array>, i: Int, j: Int): Int { + //定义本次记录的路径长度 + var ans = 0 + //四个方向相当于图的四个分支,每个方向做深度优先搜索, + for (d in dirs) { + val x = i + d[0]//下一个元素行坐标 + val y = j + d[1]//下一个元素列坐标 + /** + * 校验下标合法范围 + */ + if (0 <= x && x < m && 0 <= y && y < n ){ + //表示递增的 + if( matrix[x][y] > matrix[i][j]){ + //每次查找如果比当前的大就替换 + ans = Math.max(ans, dfs(matrix, x, y)) + } + } + } + //这里+1表示到达当前一步 + return ++ans +} + + +var m = 0 +var n = 0 +val dirs = arrayOf>(arrayOf(0, 1), arrayOf(1, 0), arrayOf(0, -1), arrayOf(-1, 0)) + + +/** + 记忆化深度优先搜索 + + 将递归的结果存储下来,这样每个子问题只需要计算一次。 + 从上面的分析中,我们知道在淳朴的深度优先搜索方法中有许多重复的计算。 + 一个优化途径是我们可以用一个集合来避免一次深度优先搜索中的重复访问。 + 该优化可以将一次深度优先搜索的时间复杂度优化到 O(mn)O(mn),总时间复杂度 O(m^2n^2)。 + + **/ + +fun longestIncreasingPath2(matrix: Array>): Int { + + if (matrix.size == 0) return 0 + //几列 + m = matrix.size + //几行 + n = matrix[0].size + //最长路径 + var ans = 0 + + val cache = Array(m) { IntArray(n) } + for (i in 0 until m) { + for (j in 0 until n) { + //每个顶点做四个方向的深度优先搜索 + ans = Math.max(ans, dfs2(matrix, i, j,cache)); + } + } + + return ans +} + +/** + * 记忆 深度优先搜索 + */ +fun dfs2( + matrix: Array>, + i: Int, + j: Int, + cache: Array +): Int { + //从缓存获取结果 + if (cache[i][j] != 0) return cache[i][j] + + //定义本次记录的路径长度 + var ans = 0 + //四个方向相当于图的四个分支,每个方向做深度优先搜索, + for (d in dirs) { + val x = i + d[0]//下一个元素行坐标 + val y = j + d[1]//下一个元素列坐标 + /** + * 校验下标合法范围 + */ + if (0 <= x && x < m && 0 <= y && y < n ){ + //表示递增的 + if( matrix[x][y] > matrix[i][j]){ + //每次查找如果比当前的大就替换 + //缓存每个节点的最长路径 + cache[i][j] = Math.max(ans, dfs2(matrix, x, y,cache)) + } + } + } + //这里+1表示到达当前一步 + return ++cache[i][j] +} diff --git a/app/src/main/java/com/wangpos/datastructure/leetcode/LeetCode382.kt b/app/src/main/java/com/wangpos/datastructure/leetcode/LeetCode382.kt new file mode 100644 index 0000000..fc3666e --- /dev/null +++ b/app/src/main/java/com/wangpos/datastructure/leetcode/LeetCode382.kt @@ -0,0 +1,41 @@ +package com.wangpos.datastructure.leetcode + +import java.util.* + +/** + * 给定一个单链表,随机选择链表的一个节点,并返回相应的节点值。保证每个节点被选的概率一样。 + +进阶: +如果链表十分大且长度未知,如何解决这个问题?你能否使用常数级空间复杂度实现? + + */ +fun main() { + val head = ListNode(1) + head.next = ListNode(2) + head.next!!.next = ListNode(3) + + val solution = Solution382(head) + + println("结果:${solution.random}") +} + + +internal class Solution382(private val head: ListNode) { + + val random: Int + get() { + var res = head.`val` + var no = head.next + var i = 2 + val random = Random() + while (no != null) { + if (random.nextInt(i) === 0) { + res = no.`val` + } + i++ + no = no.next + } + return res + + } +} \ No newline at end of file diff --git a/app/src/main/java/com/wangpos/datastructure/leetcode/LeetCode398.kt b/app/src/main/java/com/wangpos/datastructure/leetcode/LeetCode398.kt new file mode 100644 index 0000000..2dec387 --- /dev/null +++ b/app/src/main/java/com/wangpos/datastructure/leetcode/LeetCode398.kt @@ -0,0 +1,41 @@ +package com.wangpos.datastructure.leetcode + +import java.util.* + + +/** + * 给定一个可能含有重复元素的整数数组,要求随机输出给定的数字的索引。 您可以假设给定的数字一定存在于数组中。 + */ +fun main() { + + val array = arrayOf(1,2,3,4,4,4) + val solution398 = Solution398(array.toIntArray()) + + println("结果:${solution398.pick(4)}") +} + +internal class Solution398(nums: IntArray) { + var mp = mutableMapOf>() + + init { + for (i in nums.indices) { + if (mp.containsKey(nums[i]) === false) { + val list = ArrayList() + list.add(i) + mp[nums[i]] = list + } else { + mp[nums[i]]?.add(i) + } + } + + } + + fun pick(target: Int): Int { + val r = Random() + val index = mp[target]!!.size + val random = r.nextInt(index) + println(random) + return mp[target]!!.get(random) + } +} + diff --git a/app/src/main/java/com/wangpos/datastructure/leetcode/LeetCode478.kt b/app/src/main/java/com/wangpos/datastructure/leetcode/LeetCode478.kt new file mode 100644 index 0000000..11f900b --- /dev/null +++ b/app/src/main/java/com/wangpos/datastructure/leetcode/LeetCode478.kt @@ -0,0 +1,24 @@ +package com.wangpos.datastructure.leetcode + +import java.util.* + + +fun main() { + val obj = LeetCode478(10.0,0.0,0.0) + + println("结果:${Arrays.toString(obj.randPoint())}") +} +internal class LeetCode478(var rad: Double, var xc: Double, var yc: Double) { + + fun randPoint(): DoubleArray { + val x0 = xc - rad + val y0 = yc - rad + + while (true) { + val xg = x0 + Math.random() * rad * 2.0 + val yg = y0 + Math.random() * rad * 2.0 + if (Math.sqrt(Math.pow(xg - xc, 2.0) + Math.pow(yg - yc, 2.0)) <= rad) + return doubleArrayOf(xg, yg) + } + } +} diff --git a/app/src/main/java/com/wangpos/datastructure/leetcode/readme b/app/src/main/java/com/wangpos/datastructure/leetcode/readme deleted file mode 100644 index 9286eca..0000000 --- a/app/src/main/java/com/wangpos/datastructure/leetcode/readme +++ /dev/null @@ -1,15 +0,0 @@ -基础数据结构 - -数组 -链表 -栈 -队列 -树 - -高级数据结构 - -优先队列 -图 -前缀树 -线段树 -树状数组 \ No newline at end of file diff --git a/app/src/main/java/com/wangpos/datastructure/leetcode/readme.md b/app/src/main/java/com/wangpos/datastructure/leetcode/readme.md new file mode 100644 index 0000000..5fc585d --- /dev/null +++ b/app/src/main/java/com/wangpos/datastructure/leetcode/readme.md @@ -0,0 +1,40 @@ +LeetCode全部题型 + +- 数组(215) +- 动态规划(176) +- 数学(164) +- 字符串(153) +- 树(125) +- 哈希表(122) +- 深度优先搜索(115) +- 二分查找(82) +- 贪心算法(69) +- 广度优先搜索(63) +- 双指针(60) +- 栈(54) +- 回溯算法(53) +- 设计(43) +- 位运算(41) +- 排序(39) +- 图(38) +- 链表(37) +- 堆(34) +- 并查表(28) +- 滑动窗口(20) +- 分治算法(19) +- 字典树(17) +- 递归(15) +- 线段树(11) +- Ordered Map(10) +- 队列(9) +- 极小化极大(8) +- 树状数组(6) +- LineSweep(6) +- Random(6) +- 拓扑排序(6) +- 脑筋急转弯(5) +- 几何(5) +- 二叉搜索树(2) 1038 1214 +- Reject Sampling(2) 478 +- 蓄水池抽样(2) 382 398 +- 记忆化(1) 329 \ No newline at end of file From 268eb551d78d5f44a83e1b7de8d56cf2ae850486 Mon Sep 17 00:00:00 2001 From: qiyue Date: Sat, 11 Jan 2020 10:57:39 +0800 Subject: [PATCH 04/41] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .idea/workspace.xml | 296 +++++++++--------- .../datastructure/leetcode/LeetCode207.java | 77 +++++ .../datastructure/leetcode/LeetCode207.kt | 22 ++ .../datastructure/leetcode/LeetCode292.kt | 18 ++ .../datastructure/leetcode/LeetCode319.kt | 16 + .../wangpos/datastructure/leetcode/readme.md | 2 +- 6 files changed, 274 insertions(+), 157 deletions(-) create mode 100644 app/src/main/java/com/wangpos/datastructure/leetcode/LeetCode207.java create mode 100644 app/src/main/java/com/wangpos/datastructure/leetcode/LeetCode207.kt create mode 100644 app/src/main/java/com/wangpos/datastructure/leetcode/LeetCode292.kt create mode 100644 app/src/main/java/com/wangpos/datastructure/leetcode/LeetCode319.kt diff --git a/.idea/workspace.xml b/.idea/workspace.xml index 11ec409..0128765 100644 --- a/.idea/workspace.xml +++ b/.idea/workspace.xml @@ -13,16 +13,12 @@ - - - - - - - - + + + + - + @@ -3737,7 +3729,7 @@ - + - + + - + + - - - @@ -4141,8 +4135,8 @@ - - + + @@ -4152,14 +4146,13 @@ - + - @@ -4172,6 +4165,7 @@ + @@ -4740,6 +4734,72 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -4954,13 +4915,6 @@ - - - - - - - @@ -4968,13 +4922,6 @@ - - - - - - - @@ -5030,9 +4977,7 @@ - - - + @@ -5041,17 +4986,34 @@ + - - + + + + + + + + + + + + + + + - - + + + + + @@ -5062,26 +5024,92 @@ - + - - + + - + - - + + - + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -5089,21 +5117,62 @@ - + - - + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + diff --git a/README.md b/README.md index 542e081..725a374 100644 --- a/README.md +++ b/README.md @@ -13,6 +13,7 @@ - [选择排序](https://github.com/UCodeUStory/DataStructure/blob/master/app/src/main/java/com/wangpos/datastructure/sort/OptionSortActivity.java) - [冒泡排序](https://github.com/UCodeUStory/DataStructure/blob/master/app/src/main/java/com/wangpos/datastructure/sort/BubbleSortActivity.java) - [线程与锁详解](https://github.com/UCodeUStory/DataStructure/blob/master/app/src/main/java/com/wangpos/datastructure/java/JavaThreadActivity.java) +- [二叉树的性质](https://github.com/UCodeUStory/DataStructure/blob/master/sources/binearyTree.md) - 二叉树的遍历 - 二叉排序树 - 红黑树 @@ -26,6 +27,7 @@ - 有向图的创建 - [拓扑排序-邻接矩阵存储-Kahn算法](https://github.com/UCodeUStory/DataStructure/blob/master/app/src/main/java/com/wangpos/datastructure/graph/TopologicalOrderActivity.java) - 拓扑排序-邻接矩阵存储-深度优先搜索算法 +- [邻接矩阵和邻接表比较](https://github.com/UCodeUStory/DataStructure/blob/master/sources/matrix_table.md) - [最短路径算法之Dijkstra算法(狄克斯特拉算法](https://github.com/UCodeUStory/DataStructure/blob/master/app/src/main/java/com/wangpos/datastructure/graph/DjstaActivity.java) - [ArrayList实现原理](https://github.com/UCodeUStory/DataStructure/blob/master/app/src/main/java/com/wangpos/datastructure/java/mylist/CJArrayList.java) - [LinkList双向实现](https://github.com/UCodeUStory/DataStructure/blob/master/app/src/main/java/com/wangpos/datastructure/java/mylist/CJArrayList.java) diff --git a/app/src/main/java/com/wangpos/datastructure/leetcode/LeetCode1203.java b/app/src/main/java/com/wangpos/datastructure/leetcode/LeetCode1203.java new file mode 100644 index 0000000..8954932 --- /dev/null +++ b/app/src/main/java/com/wangpos/datastructure/leetcode/LeetCode1203.java @@ -0,0 +1,246 @@ +package com.wangpos.datastructure.leetcode; + +import android.support.annotation.NonNull; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.LinkedList; +import java.util.List; +import java.util.Queue; + +/** + * + * 项目之间的依赖关系,用拓扑排序解决。这比较明显。 + * + * 难点在于怎么理解“ 同一小组的项目,排序后在列表中彼此相邻 ”。 + * + * + * 这个题通过提示可以知道使用两层拓扑排序,但是坑还是挺多的。 + * 1.需要给单独的项目创建一个组 + * 2.需要通过项目ID找到关联的组,同时需要维护组本身的序列 + * 一开始想图省事,用一个group[]表示,后来发现这样有耦合问题。改用List维护组本身,用数组维护项目到组的映射关系,初始化List为m个,如果遇到单独的项目, + * 则把当前List大小设置为组ID分配给这个项目。通过这个解决了项目ID和组ID耦合的问题。 + * + */ +public class LeetCode1203 { + + public static void main(String args[]) { + int[] group = new int[]{-1, -1, 1, 0, 0, 1, 0, -1}; + int n = 8; + int m = 2; + List> beforeItems = new ArrayList<>(); + //[[],[6],[5],[6],[3,6],[],[],[]] + beforeItems.add(createItem()); + beforeItems.add(createItem()); + beforeItems.get(beforeItems.size() - 1).add(6); + beforeItems.add(createItem()); + beforeItems.get(beforeItems.size() - 1).add(5); + beforeItems.add(createItem()); + beforeItems.get(beforeItems.size() - 1).add(6); + beforeItems.add(createItem()); + beforeItems.get(beforeItems.size() - 1).add(3); + beforeItems.get(beforeItems.size() - 1).add(6); + beforeItems.add(createItem()); + beforeItems.add(createItem()); + beforeItems.add(createItem()); + + int[] result = new LeetCode1203().sortItems(8, 2, group, beforeItems); + System.out.println(Arrays.toString(result)); + + } + + @NonNull + private static List createItem() { + return new ArrayList(); + } + + + Listqueue = new LinkedList<>(); + + + //项目 + static class Item { + //项目id + int id; + + //初始化入度 + int inputCnt; + //下一个项目 + List nextItems = new ArrayList<>(); + + Item(int id) { + this.id = id; + } + } + + //组 + static class Group { + //组id + int id; + + //入度 + int inputCnt; + + List items = new ArrayList<>(); + //下一个 组 + List nextGroups = new ArrayList<>(); + + Group(int id) { + this.id = id; + } + } + + /** + * 使用邻接表的形式 + * @param n + * @param m + * @param group + * @param beforeItems + * @return + */ + public int[] sortItems(int n, int m, int[] group, List> beforeItems) { + //项目数组 + Item[] items = new Item[n]; + + //用来保存已经绑定过item的group数组 + Group[] itemToGroup = new Group[n]; + + //组 + List oriGroups = new ArrayList<>(); + + //初始化组种类 + for (int j = 0; j < m; j++) { + oriGroups.add(new Group(j)); + } + + //初始化项目 + for (int i = 0; i < n; i++) { + items[i] = new Item(i); + } + + /** + * 遍历每个项目,所属组 + */ + for (int i = 0; i < group.length; i++) { + int groupId = group[i]; + if (groupId == -1) {// 项目不属于任何组 + //创建一个新组 + Group temp = new Group(oriGroups.size()); + //保存到组列表 + oriGroups.add(temp); + //组绑定这个项目,因为项目是按顺序的所以i就是这个项目 + temp.items.add(i); + itemToGroup[i] = temp; + } else { + //根据组id 绑定项目 + oriGroups.get(groupId).items.add(i); + itemToGroup[i] = oriGroups.get(groupId); + } + } + + for (int i = 0; i < beforeItems.size(); i++) { + List array = beforeItems.get(i); + //初始化入度 + items[i].inputCnt = array.size(); + for (Integer itemId : array) { + //每个项目的下一个项目 + items[itemId].nextItems.add(i); + //获取绑定项目后的组 + Group beforeGroup = itemToGroup[itemId]; + //当前组 + Group curGroup = itemToGroup[i]; + if (beforeGroup != curGroup) { + //前一个组保存他的下一个组 + beforeGroup.nextGroups.add(curGroup); + //当前组入度多1 + curGroup.inputCnt++; + } + } + } + + Queue groupQueue = new LinkedList<>(); + + //找到入度为0的组添加到待遍历的队列中 + for (Group ele : oriGroups) { + if (ele.inputCnt == 0) { + groupQueue.offer(ele); + } + } + + if (groupQueue.isEmpty()) { + return new int[0]; + } + + int[] result = new int[n]; + int resultIndex = 0; + while (!groupQueue.isEmpty()) { + int size = groupQueue.size(); + for (int i = 0; i < size; i++) { + Group curGroup = groupQueue.poll(); + Queue itemQueue = new LinkedList<>(); + if (curGroup.items.isEmpty()) { + continue; + } + + //再进行item拓扑排序 + for (int temp : curGroup.items) { + if (items[temp].inputCnt == 0) { + itemQueue.offer(temp); + } + } + + if (itemQueue.isEmpty()) { + return new int[0]; + } + + // + while (!itemQueue.isEmpty()) { + int itemQueueSize = itemQueue.size(); + for (int j = 0; j < itemQueueSize; j++) { + Integer itemId = itemQueue.poll(); + //保存结果 + result[resultIndex++] = itemId; + //遍历下一个 + for (int nextItemId : items[itemId].nextItems) { + items[nextItemId].inputCnt--; + if (items[nextItemId].inputCnt == 0 && curGroup.items.contains(nextItemId)) { + itemQueue.offer(nextItemId); + } + } + } + } + + //项目中存在环 + for (int itemId : curGroup.items) { + if (items[itemId].inputCnt > 0) { + return new int[0]; + } + } + + //遍历下一个组 + for (Group nextGroup : curGroup.nextGroups) { + nextGroup.inputCnt--; + if (nextGroup.inputCnt == 0) { + groupQueue.offer(nextGroup); + } + } + } + } + //组中存在环 + for (Group ele : oriGroups) { + if (ele.inputCnt > 0) { + return new int[0]; + } + } + + for (int k = 0; k < items.length; k++) { + if (items[k].inputCnt > 0) { + return new int[0]; + } + } + + return result; + } + + +} diff --git a/app/src/main/java/com/wangpos/datastructure/leetcode/LeetCode207.java b/app/src/main/java/com/wangpos/datastructure/leetcode/LeetCode207.java index d9d6154..f13a2b2 100644 --- a/app/src/main/java/com/wangpos/datastructure/leetcode/LeetCode207.java +++ b/app/src/main/java/com/wangpos/datastructure/leetcode/LeetCode207.java @@ -2,6 +2,34 @@ import java.util.LinkedList; +/** + * + * 广度优先搜索 通过保存一个入度表 + * + * 然后取出入度为0的元素添加到队列 + * + * 遍历入度为0的队列,如果到下一个有边,将下一个入度--1,当所有下一个边都--1 相当于移除这个点 + * + * 如果下一个点的入度为0 就添加到遍历的队列 + * + * 在遍历的时候计数一下看看是否所有点都遍历到可以判断环形 + * + * + * 深度优先搜索, + * + * 通过flag数组标识 0 未遍历 1遍历中,-1遍历完成 + * + * 如果遍历下一个点的时候判断1标识存在环 + * + * 遍历下一个节点,然后再递归调用 + * + * 邻接矩阵通过 graph[][]==1判断有没有边 + * 通过遍历依赖关系列表 [0]位置出现的次数就是入度,比如[1,3]证明 3到1的边,1的入度为1 + * + * 邻接表,可以通过数组中集合的个数表示入度 + * + * + */ public class LeetCode207 { /** @@ -33,7 +61,7 @@ public boolean canFinish(int numCourses, int[][] prerequisites) { Integer pre = queue.removeFirst(); //每次遍历,相当于从这个起点出发的所有边都遍历到了,所以相当于这个点遍历完就完成了一个课程,这就是广度优先搜索 numCourses--; - // + //遍历其余边 for (int[] req : prerequisites) { //广度优先搜索就是逐个遍历,任意找到一个含有当前起点的边,如果不包含就跳过 if (req[1] != pre) continue; @@ -60,15 +88,25 @@ public boolean canFinish2(int numCourses, int[][] prerequisites) { return true; } + /** + * 这里使用了一个小技巧,就是通过标识 0未被访问,1 标识正在被这条分支访问中,-1标识这个分支访问结束 + * 所以可以很容易判断 如果被访问状态是1状态就说明存在了环路 + * + * @param adjacency + * @param flags + * @param i + * @return + */ private boolean dfs(int[][] adjacency, int[] flags, int i) { - if (flags[i] == 1) return false;//表示此点被再次访问 + if (flags[i] == 1) return false;//表示本次访问的节点还没访问结束又被子节点访问了,所以就存在了环路 if (flags[i] == -1) return true;//表示此点已被访问 - //当前点 - flags[i] = 1; + if (flags[i] == 0) flags[i] = 1; //当前已被访问,继续这个点的子节点 for (int j = 0; j < adjacency.length; j++) { //adjacency[i][j] == 1 表示之间有边 if (adjacency[i][j] == 1 && !dfs(adjacency, flags, j)) return false; + } + ///当前已被访问完毕,子节点也访问完毕 flags[i] = -1; return true; } diff --git a/app/src/main/java/com/wangpos/datastructure/leetcode/LeetCode210.java b/app/src/main/java/com/wangpos/datastructure/leetcode/LeetCode210.java new file mode 100644 index 0000000..ed8afae --- /dev/null +++ b/app/src/main/java/com/wangpos/datastructure/leetcode/LeetCode210.java @@ -0,0 +1,91 @@ +package com.wangpos.datastructure.leetcode; + +import java.util.LinkedList; +import java.util.Stack; + +public class LeetCode210 { + + public int[] findOrder(int numCourses, int[][] prerequisites) { + + Stack stack = new Stack(); + int[] array = new int[0]; + if (canFinish2(numCourses, prerequisites, stack)) { + array = new int[numCourses]; + } else { + return array; + } + + int index = 0; + while (!stack.isEmpty()) { + array[index] = stack.pop(); + index++; + } + return array; + } + + /** + * 时间复杂度: O(N),其中NN为课程数。我们需要要对森林中的所有结点执行完全的深度优先搜索。之所以是森林而不是图,是因为并非所有结点都连接在一起。也可能存在不连通的部分。 + * 空间复杂度: O(N), 递归栈占用的空间(不是用于存储拓扑排序的栈)。 + * 利用深度优先搜索 + */ + + public boolean canFinish2(int numCourses, int[][] prerequisites, Stack stack) { + int[][] adjacency = new int[numCourses][numCourses]; + //定义节点标识 + int[] flags = new int[numCourses]; + //将数组依赖关系变成矩阵 + for (int[] cp : prerequisites) + adjacency[cp[1]][cp[0]] = 1; + + for (int i = 0; i < numCourses; i++) { + if (!dfs(numCourses, adjacency, flags, i, stack)) { + return false; + } + } + return true; + } + + /** + * 这里使用了一个小技巧,就是通过标识 0未被访问,1 标识正在被这条分支访问中,-1标识这个分支访问结束 + * 所以可以很容易判断 如果被访问状态是1状态就说明存在了环路 + * + * @param adjacency + * @param flags + * @param i + * @return + */ + private boolean dfs(int numCourses, int[][] adjacency, int[] flags, int i, Stack stack) { + if (flags[i] == 1) return false;//表示本次访问的节点还没访问结束又被子节点访问了,所以就存在了环路 + if (flags[i] == -1) { + return true;//表示此点已被访问 + } + if (flags[i] == 0) flags[i] = 1; //当前已被访问,继续这个点的子节点 + for (int j = 0; j < adjacency.length; j++) { + //adjacency[i][j] == 1 判断有边,如果result false证明有环就return + if (adjacency[i][j] == 1 && !dfs(numCourses, adjacency, flags, j, stack)) return false; + + //等价代码 +// if (adjacency[i][j] == 1) { +// boolean result = dfs(numCourses, adjacency, flags, j, stack); +// if (!result) { +// //有环路 +// return false; +// } +// } + + } + ///当前已被访问完毕,子节点也访问完毕 + + flags[i] = -1; + //保存遍历 + stack.push(i); + return true; + } + + + /** + * 方法二: 利用结点的入度 + */ + + +} diff --git a/app/src/main/java/com/wangpos/datastructure/leetcode/LeetCode210.kt b/app/src/main/java/com/wangpos/datastructure/leetcode/LeetCode210.kt new file mode 100644 index 0000000..7d9a6f0 --- /dev/null +++ b/app/src/main/java/com/wangpos/datastructure/leetcode/LeetCode210.kt @@ -0,0 +1,37 @@ +package com.wangpos.datastructure.leetcode + +import java.util.* + +/** + * 现在你总共有 n 门课需要选,记为 0 到 n-1。 + +在选修某些课程之前需要一些先修课程。 例如,想要学习课程 0 ,你需要先完成课程 1 ,我们用一个匹配来表示他们: [0,1] + +给定课程总量以及它们的先决条件,返回你为了学完所有课程所安排的学习顺序。 + +可能会有多个正确的顺序,你只要返回一种就可以了。如果不可能完成所有课程,返回一个空数组 + */ + +fun main() { + + val course = arrayOf( + arrayOf(1, 0).toIntArray(), + arrayOf(2, 0).toIntArray(), + arrayOf(3, 1).toIntArray(), + arrayOf(3, 2).toIntArray() + ) + + val num = course.size + + //深度优先搜索,判断无环就可以完全修,并且保存所有路径 + + //将课程数组转化成邻接矩阵 + + // + + val result = LeetCode210().findOrder(4,course) + + println("result=${Arrays.toString(result)}") + + +} \ No newline at end of file diff --git a/app/src/main/java/com/wangpos/datastructure/leetcode/LeetCode307.kt b/app/src/main/java/com/wangpos/datastructure/leetcode/LeetCode307.kt new file mode 100644 index 0000000..37a5af0 --- /dev/null +++ b/app/src/main/java/com/wangpos/datastructure/leetcode/LeetCode307.kt @@ -0,0 +1,81 @@ +package com.wangpos.datastructure.leetcode + +/** + * 给定一个整数数组  nums,求出数组从索引 i 到 j  (i ≤ j) 范围内元素的总和,包含 i,  j 两点。 + +update(i, val) 函数可以通过将下标为 i 的数值更新为 val,从而对数列进行修改。 + + +频繁计算总和可以用这总结构,同时这种结构更新效率不再是O(1) + */ +fun main() { + + +} + +class NumArray(nums: IntArray) { + + lateinit var tree: IntArray + + init { + if (nums.size > 0) { + n = nums.size + tree = IntArray(n * 2) + buildTree(nums) + } + } + + private fun buildTree(nums: IntArray) { + var i = n; + var j = 0; + while (i < 2 * n) { + //初始化叶子节点 + tree[i] = nums[j] + i++ + j++ + } + + i = n-1 + //初始化和 + while (i>0){ + tree[i] = tree[i * 2] + tree[i * 2 + 1] + i-- + } + } + + fun update(i: Int, `val`: Int) { + + } + + fun sumRange(i: Int, j: Int): Int { + + } + +} + + +/** + * 一般方式 sumRang 时间复杂度为O(n) + * +private int[] nums; +public int sumRange(int i, int j) { +int sum = 0; +for (int l = i; l <= j; l++) { +sum += data[l]; +} +return sum; +} + +public int update(int i, int val) { +nums[i] = val; +} + */ + +/** +sqrt 分解 +其思想是将数组分割成块,块的长度为 sqrt n +​ +。然后我们计算每个块的和,并将其存储在辅助存储器 b 中。要查询 RSQ(i, j),我们将添加位于内部的所有块和部分在范围 [i\ldots j][i…j] 重叠的块的总和。 + + + */ \ No newline at end of file diff --git a/app/src/main/java/com/wangpos/datastructure/leetcode/LeetCode329.kt b/app/src/main/java/com/wangpos/datastructure/leetcode/LeetCode329.kt index 0ac9e55..9fcb1b7 100644 --- a/app/src/main/java/com/wangpos/datastructure/leetcode/LeetCode329.kt +++ b/app/src/main/java/com/wangpos/datastructure/leetcode/LeetCode329.kt @@ -76,7 +76,9 @@ fun dfs(matrix: Array>, i: Int, j: Int): Int { } } } - //这里+1表示到达当前一步 + //这里+1表示到达当前一步,如果四个方向都没有找到递增的就返回1 + // ,回溯一次多了1,回溯一次多了1,所以每次判断哪个路径回溯的最多, + //最终回溯到终点就是最长路径 ans return ++ans } diff --git a/app/src/main/java/com/wangpos/datastructure/leetcode/LeetCode444.java b/app/src/main/java/com/wangpos/datastructure/leetcode/LeetCode444.java new file mode 100644 index 0000000..fedf2ac --- /dev/null +++ b/app/src/main/java/com/wangpos/datastructure/leetcode/LeetCode444.java @@ -0,0 +1,110 @@ +package com.wangpos.datastructure.leetcode; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Set; + +/** + * 验证原始的序列 org 是否可以从序列集 seqs 中唯一地重建。序列 org 是 1 到 n 整数的排列, + * + * 其中 1 ≤ n ≤ 10^4。重建是指在序列集 seqs 中构建最短的公共超序列。(即使得所有  seqs 中的序列都是该最短序列的子序列)。确定是否只可以从 seqs 重建唯一的序列,且该序列就是 org + */ +public class LeetCode444 { + + public boolean sequenceReconstruction(int[] org, List> seqs) { + int n = org.length; + + if (n == 0 || seqs.size() == 0) { + return false; + } + + // 考虑seqs里头元素为空列表的情况, 已经数字超过n或者<=0的情况 + Set numSet = new HashSet<>(); + for (List list : seqs) { + for (Integer num: list) { + if (num <= 0 || num > n) { + return false; + } + numSet.add(num); + } + } + + if (numSet.size() < n) { + return false; + } + + ArrayList[] adj = new ArrayList[n + 1]; + + for (int i = 1; i <= n; i++) { + adj[i] = new ArrayList<>(); + } + + createTable(seqs, adj); + + // 计算每个节点的入度 + int[] inDegree = new int[n + 1]; + + for (int i = 1; i <= n; i++) { + for (int j = 0; j < adj[i].size(); j++) { + int w = adj[i].get(j); + inDegree[w]++; + } + } + + // 计算入度为0的节点,添加到队列中 + LinkedList queue = new LinkedList<>(); + for (int i = 1; i <= n; i++) { + if (inDegree[i] == 0) { + queue.addLast(i); + } + } + + // 入度为0的节点有多个,就会产生多种序列,或者没有入度为0的,不满足题目要求 + if (queue.size() != 1) { + return false; + } + + int index = 0; + while (!queue.isEmpty()) { + int num = queue.removeFirst(); + if (org[index] != num) { + return false; + } + index++; + + // 删除当前节点后,所有当前节点的下一个节点的入度为0的个数,超过1则说明序列不唯一 + int nextZeroInDegreeCount = 0; + for (int j = 0; j < adj[num].size(); j++) { + int w = adj[num].get(j); + //遍历邻接表中相邻边的入度都减1 + inDegree[w]--; + if (inDegree[w] == 0) { + nextZeroInDegreeCount++; + //去掉一个结点后,如果入度为0的节点增加了不止1个,说明有多处一个分支,就直接返回false + if (nextZeroInDegreeCount > 1) { + return false; + } + + queue.addLast(w); + } + } + } + + return index == n; + } + + private void createTable(List> seqs, ArrayList[] adj) { + // 构建邻接表 + for (int i = 0; i < seqs.size(); i++) { + List pair = seqs.get(i); + + for (int j = 0; j < pair.size() - 1; j++) { + //数组中链表同样初始化 + adj[pair.get(j)].add(pair.get(j+1)); + } + } + } + +} diff --git a/app/src/main/java/com/wangpos/datastructure/leetcode/Test17.java b/app/src/main/java/com/wangpos/datastructure/leetcode/Test17.java new file mode 100644 index 0000000..589f078 --- /dev/null +++ b/app/src/main/java/com/wangpos/datastructure/leetcode/Test17.java @@ -0,0 +1,64 @@ +package com.wangpos.datastructure.leetcode; + +public class Test17 { + + public static void main() { + int[] nums = new int[]{1, 2, 3, 4}; + int[] count = new Test17().decompressRLElist(nums); + System.out.println(count.length); + } + + public int[] decompressRLElist(int[] nums) { + + int count = 0; + int index = 0; + int[] resultArray; + for (int i = 0; i < nums.length; i++) { + // 0 1 2 3 4 5 + if ((i + 1) % 2 != 0) { + count += nums[i]; + } + } + resultArray = new int[count]; + + for (int i = 0; i < nums.length; i++) { + if ((i + 1) % 2 != 0) { + for (int j = 0; j < nums[i]; j++) { + resultArray[index] = nums[i + 1]; + index++; + } + } + + } + return resultArray; + + } + + public int[][] matrixBlockSum(int[][] mat, int K) { + + int[][] resultArray = new int[mat.length][mat[0].length]; + + for (int i = 0; i < mat.length; i++) { +//i - K <= r <= i + K, j - K <= c <= j + K +// for (int m = 0; m < mat[i].length; m++) { + int aa = i-K; + if(aa<0){ + aa=0; + } + int sum = 0; + for (int a = aa; a <= i + K && a < mat.length; a++) { + int bb = i-K; + if (bb<0){ + bb = 0; + } + for (int b=bb; b <= i + K && b < mat[i].length ; b++) { + sum += mat[a][b]; + } + } +// resultArray[i][m] = sum; +// } + } + + return resultArray; + } +} diff --git a/app/src/main/java/com/wangpos/datastructure/leetcode/Test17.kt b/app/src/main/java/com/wangpos/datastructure/leetcode/Test17.kt new file mode 100644 index 0000000..0c44ae4 --- /dev/null +++ b/app/src/main/java/com/wangpos/datastructure/leetcode/Test17.kt @@ -0,0 +1,20 @@ +package com.wangpos.datastructure.leetcode + +import java.util.* + +fun main() { + + val array = arrayOf(1,2,3,4).toIntArray() + val count = Test17().decompressRLElist(array) + +// println(Arrays.toString(count)) +// + val arrayMatrix = arrayOf(arrayOf(1,2,3).toIntArray(), + arrayOf(4,5,6).toIntArray(),arrayOf(7,8,9).toIntArray()) + + val resultArray = Test17().matrixBlockSum(arrayMatrix,1) + + resultArray.forEach { + println(Arrays.toString(it)) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/wangpos/datastructure/leetcode/Test18.java b/app/src/main/java/com/wangpos/datastructure/leetcode/Test18.java new file mode 100644 index 0000000..6eac650 --- /dev/null +++ b/app/src/main/java/com/wangpos/datastructure/leetcode/Test18.java @@ -0,0 +1,32 @@ +package com.wangpos.datastructure.leetcode; + +import java.util.Arrays; + +public class Test18 { + public static void main(String[] args) { + System.out.println("Hello World"); + System.out.println(Arrays.toString(new Test18().getNoZeroIntegers(1010))); + } + + public int[] getNoZeroIntegers(int n) { + + for (int a = 1; a < n; a++) { + int c = n - a; + String as = a+""; + if(as.contains("0")){ + continue; + } + String s = c+""; + if(s.contains("0")){ + continue; + } + int result[] = new int[2]; + result[0] = a; + result[1] = c; + return result; + } + return new int[0]; + } + + +} diff --git a/app/src/main/java/com/wangpos/datastructure/leetcode/readme.md b/app/src/main/java/com/wangpos/datastructure/leetcode/readme.md index cd03a3f..4e14c1b 100644 --- a/app/src/main/java/com/wangpos/datastructure/leetcode/readme.md +++ b/app/src/main/java/com/wangpos/datastructure/leetcode/readme.md @@ -28,13 +28,16 @@ LeetCode全部题型 - Ordered Map(10) - 队列(9) - 极小化极大(8) -- 树状数组(6) +- 树状数组(6) + - 又称 二叉索引树 又以其发明者命名为 Fenwick 树。其初衷是解决数据压缩里的累积频率的计算问题,现多用于高效计算数列的前缀和、区间和它可以以 O(logn) 的时间得到任意前缀和 + 并同时支持在 O(\log n)O(logn) 时间内支持动态单点值的修改。空间复杂度 O(n)O(n)。 + - LineSweep(6) - Random(6) -- 拓扑排序(6) -- 脑筋急转弯(5) 292 +- 拓扑排序(6) #207 #210 #329 #444 #1203 +- 脑筋急转弯(5) #292 - 几何(5) -- 二叉搜索树(2) 1038 1214 -- Reject Sampling(2) 478 -- 蓄水池抽样(2) 382 398 -- 记忆化(1) 329 \ No newline at end of file +- 二叉搜索树(2) #1038 #1214 +- Reject Sampling(2) #478 +- 蓄水池抽样(2) #382 #398 +- 记忆化(1) #329 \ No newline at end of file diff --git a/sources/binearyTree.md b/sources/binearyTree.md new file mode 100644 index 0000000..84888c4 --- /dev/null +++ b/sources/binearyTree.md @@ -0,0 +1,13 @@ +### 二叉树的性质 + + +若对含 n 个结点的完全二叉树从上到下且从左至右进行 1 至 n 的编号,则对完全二叉树中任意一个编号为 i 的结点: + +(1) 若 i=1,则该结点是二叉树的根,无双亲, 否则,编号为 [i/2] 的结点为其双亲结点;   + +(2) 若 2i>n,则该结点无左孩子,  否则,编号为 2i 的结点为其左孩子结点; + +(3) 若 2i+1>n,则该结点无右孩子结点,  否则,编号为2i+1 的结点为其右孩子结点。 + + +**注意 编号是从1开始才有这个关系,如果是从0开始就不满住这个关系,所以切记 \ No newline at end of file diff --git a/sources/matrix_table.md b/sources/matrix_table.md new file mode 100644 index 0000000..16ae175 --- /dev/null +++ b/sources/matrix_table.md @@ -0,0 +1,43 @@ +### 邻接矩阵和邻接表比较 + + +1. 邻接矩阵 + +图的邻接矩阵存储方式是用两个数组来表示图。一个一维数组存储图中顶点信息,一个二维数组(邻接矩阵)存储图中的边或弧的信息。 +设图G有n个顶点,则邻接矩阵是一个n*n的方阵 + +无向图的边数组是一个对称矩阵。所谓对称矩阵就是n阶矩阵的元满足aij = aji。 +即从矩阵的左上角到右下角的主对角线为轴,右上角的元和左下角相对应的元全都是相等的 + +- 从这个矩阵中,很容易知道图中的信息。 + +(1)要判断任意两顶点是否有边无边就很容易了; +(2)要知道某个顶点的度,其实就是这个顶点vi在邻接矩阵中第i行或(第i列)的元素之和; +(3)求顶点vi的所有邻接点就是将矩阵中第i行元素扫描一遍,arc[i][j]为1就是邻接点; + + +2. 邻接表 + + 一般是 数组结构,每个数组中 对应一个单链表结构;因此这种数组与链表相结合的存储方法称为邻接表 + + + 邻接表的处理方法是这样的: + + (1)图中顶点用一个一维数组存储,当然,顶点也可以用单链表来存储,不过,数组可以较容易的读取顶点的信息,更加方便。 + + (2)图中每个顶点vi的所有邻接点构成一个线性表,由于邻接点的个数不定,所以,用单链表存储,无向图称为顶点vi的边表,有向图则 + + (3)顶点表的各个结点由data和firstedge两个域表示,data是数据域,存储顶点的信息,firstedge是指针域,指向边表的第一个结点,即此顶点的第一个邻接点。 + + (4)边表结点由adjvex和next两个域组成。adjvex是邻接点域,存储某顶点的邻接点在顶点表中的下标,next则存储指向边表中下一个结点的指针。 + 对于带权值的网图,可以在边表结点定义中再增加一个weight的数据域,存储权值信息即可。 + + +3. 两者区别 + + 对于一个具有n个顶点e条边的无向图 + 它的邻接表表示有n个顶点表结点2e个边表结点 + 对于一个具有n个顶点e条边的有向图 + 它的邻接表表示有n个顶点表结点e个边表结点 + 如果图中边的数目远远小于n2称作稀疏图,这是用邻接表表示比用邻接矩阵表示节省空间; + 如果图中边的数目接近于n2,对于无向图接近于n*(n-1)称作稠密图,考虑到邻接表中要附加链域,采用邻接矩阵表示法为宜。 \ No newline at end of file From dd4ac9d595439ede2141c43da62856f858ba835a Mon Sep 17 00:00:00 2001 From: qiyue Date: Thu, 16 Jan 2020 14:10:24 +0800 Subject: [PATCH 06/41] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E6=96=B0=E4=BB=A3?= =?UTF-8?q?=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .idea/workspace.xml | 481 +++++++++++------- .../datastructure/leetcode/LeetCode307.kt | 100 +++- .../datastructure/leetcode/LeetCode307_4.java | 338 ++++++++++++ .../datastructure/leetcode/LeetCode327.java | 147 ++++++ .../wangpos/datastructure/leetcode/readme.md | 4 +- 5 files changed, 868 insertions(+), 202 deletions(-) create mode 100644 app/src/main/java/com/wangpos/datastructure/leetcode/LeetCode307_4.java create mode 100644 app/src/main/java/com/wangpos/datastructure/leetcode/LeetCode327.java diff --git a/.idea/workspace.xml b/.idea/workspace.xml index 1ed4d7d..d5c413b 100644 --- a/.idea/workspace.xml +++ b/.idea/workspace.xml @@ -13,23 +13,10 @@ - - - - - - - - - - - - - + + - - - + - BlockQueue - - Person notFull notFull.signal() count @@ -294,6 +306,9 @@ 菜品条码规则 printTree_LEFT_ROOT_RIGHT sources + source + leftChildIndex + MAX_VALUE protected @@ -3521,10 +3536,6 @@ @@ -3586,8 +3601,7 @@ - - + @@ -3658,16 +3672,12 @@ - - - - - - - - - - @@ -3735,10 +141,13 @@ + + + - + - + @@ -3751,10 +160,6 @@ - - - - @@ -3767,6 +172,10 @@ + + + + - - - + + - - @@ -4172,92 +577,21 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -