diff --git a/problems/0024.两两交换链表中的节点.md b/problems/0024.两两交换链表中的节点.md index 59ded523..66e149e6 100644 --- a/problems/0024.两两交换链表中的节点.md +++ b/problems/0024.两两交换链表中的节点.md @@ -9,6 +9,8 @@ ## 24. 两两交换链表中的节点 +https://leetcode-cn.com/problems/swap-nodes-in-pairs/ + 给定一个链表,两两交换其中相邻的节点,并返回交换后的链表。 你不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。 diff --git a/problems/0072.编辑距离.md b/problems/0072.编辑距离.md index 26f080fe..9ddca7c0 100644 --- a/problems/0072.编辑距离.md +++ b/problems/0072.编辑距离.md @@ -307,6 +307,32 @@ func Min(args ...int) int { ``` +Javascript: +```javascript +const minDistance = (word1, word2) => { + let dp = Array.from(Array(word1.length + 1), () => Array(word2.length+1).fill(0)); + + for(let i = 1; i <= word1.length; i++) { + dp[i][0] = i; + } + + for(let j = 1; j <= word2.length; j++) { + dp[0][j] = j; + } + + for(let i = 1; i <= word1.length; i++) { + for(let j = 1; j <= word2.length; j++) { + if(word1[i-1] === word2[j-1]) { + dp[i][j] = dp[i-1][j-1]; + } else { + dp[i][j] = Math.min(dp[i-1][j] + 1, dp[i][j-1] + 1, dp[i-1][j-1] + 1); + } + } + } + + return dp[word1.length][word2.length]; +}; +``` ----------------------- * 作者微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw) diff --git a/problems/0115.不同的子序列.md b/problems/0115.不同的子序列.md index 62af9d0f..014eb3cd 100644 --- a/problems/0115.不同的子序列.md +++ b/problems/0115.不同的子序列.md @@ -222,7 +222,28 @@ class SolutionDP2: Go: +Javascript: +```javascript +const numDistinct = (s, t) => { + let dp = Array.from(Array(s.length + 1), () => Array(t.length +1).fill(0)); + for(let i = 0; i <=s.length; i++) { + dp[i][0] = 1; + } + + for(let i = 1; i <= s.length; i++) { + for(let j = 1; j<= t.length; j++) { + if(s[i-1] === t[j-1]) { + dp[i][j] = dp[i-1][j-1] + dp[i-1][j]; + } else { + dp[i][j] = dp[i-1][j] + } + } + } + + return dp[s.length][t.length]; +}; +``` ----------------------- diff --git a/problems/0300.最长上升子序列.md b/problems/0300.最长上升子序列.md index 8b4ad5b1..9a7c543b 100644 --- a/problems/0300.最长上升子序列.md +++ b/problems/0300.最长上升子序列.md @@ -170,6 +170,25 @@ func lengthOfLIS(nums []int ) int { return len(dp) } ``` + +Javascript +```javascript +const lengthOfLIS = (nums) => { + let dp = Array(nums.length).fill(1); + let result = 1; + + for(let i = 1; i < nums.length; i++) { + for(let j = 0; j < i; j++) { + if(nums[i] > nums[j]) { + dp[i] = Math.max(dp[i], dp[j]+1); + } + } + result = Math.max(result, dp[i]); + } + + return result; +}; +``` *复杂度分析* - 时间复杂度:O(nlogn)。数组 nums 的长度为 n,我们依次用数组中的元素去更新 dp 数组,相当于插入最后递增的元素,而更新 dp 数组时需要进行 O(logn) 的二分搜索,所以总时间复杂度为 O(nlogn)。 - 空间复杂度:O(n),需要额外使用长度为 n 的 dp 数组。 diff --git a/problems/0406.根据身高重建队列.md b/problems/0406.根据身高重建队列.md index 2b447da4..a5f66a5d 100644 --- a/problems/0406.根据身高重建队列.md +++ b/problems/0406.根据身高重建队列.md @@ -188,15 +188,10 @@ Java: ```java class Solution { public int[][] reconstructQueue(int[][] people) { - Arrays.sort(people, new Comparator() { - @Override - public int compare(int[] o1, int[] o2) { - if (o1[0] != o2[0]) { - return Integer.compare(o2[0],o1[0]); - } else { - return Integer.compare(o1[1],o2[1]); - } - } + // 身高从大到小排(身高相同k小的站前面) + Arrays.sort(people, (a, b) -> { + if (a[0] == b[0]) return a[1] - b[1]; + return b[0] - a[0]; }); LinkedList que = new LinkedList<>(); diff --git a/problems/0503.下一个更大元素II.md b/problems/0503.下一个更大元素II.md index 3980cb0e..34ade48e 100644 --- a/problems/0503.下一个更大元素II.md +++ b/problems/0503.下一个更大元素II.md @@ -97,7 +97,18 @@ public: Java: Python: - +```python3 +class Solution: + def nextGreaterElements(self, nums: List[int]) -> List[int]: + dp = [-1] * len(nums) + stack = [] + for i in range(len(nums)*2): + while(len(stack) != 0 and nums[i%len(nums)] > nums[stack[-1]]): + dp[stack[-1]] = nums[i%len(nums)] + stack.pop() + stack.append(i%len(nums)) + return dp +``` Go: JavaScript: diff --git a/problems/0516.最长回文子序列.md b/problems/0516.最长回文子序列.md index a4f0522f..388d8d6a 100644 --- a/problems/0516.最长回文子序列.md +++ b/problems/0516.最长回文子序列.md @@ -214,7 +214,29 @@ func longestPalindromeSubseq(s string) int { } ``` +Javascript: +```javascript +const longestPalindromeSubseq = (s) => { + const strLen = s.length; + let dp = Array.from(Array(strLen), () => Array(strLen).fill(0)); + + for(let i = 0; i < strLen; i++) { + dp[i][i] = 1; + } + for(let i = strLen - 1; i >= 0; i--) { + for(let j = i + 1; j < strLen; j++) { + if(s[i] === s[j]) { + dp[i][j] = dp[i+1][j-1] + 2; + } else { + dp[i][j] = Math.max(dp[i+1][j], dp[i][j-1]); + } + } + } + + return dp[0][strLen - 1]; +}; +``` ----------------------- diff --git a/problems/0583.两个字符串的删除操作.md b/problems/0583.两个字符串的删除操作.md index d476c95a..9aef2310 100644 --- a/problems/0583.两个字符串的删除操作.md +++ b/problems/0583.两个字符串的删除操作.md @@ -149,6 +149,32 @@ class Solution: Go: +Javascript: +```javascript +const minDistance = (word1, word2) => { + let dp = Array.from(Array(word1.length + 1), () => Array(word2.length+1).fill(0)); + + for(let i = 1; i <= word1.length; i++) { + dp[i][0] = i; + } + + for(let j = 1; j <= word2.length; j++) { + dp[0][j] = j; + } + + for(let i = 1; i <= word1.length; i++) { + for(let j = 1; j <= word2.length; j++) { + if(word1[i-1] === word2[j-1]) { + dp[i][j] = dp[i-1][j-1]; + } else { + dp[i][j] = Math.min(dp[i-1][j] + 1, dp[i][j-1] + 1, dp[i-1][j-1] + 2); + } + } + } + + return dp[word1.length][word2.length]; +}; +``` ----------------------- diff --git a/problems/0647.回文子串.md b/problems/0647.回文子串.md index 31734bbc..d3b734ae 100644 --- a/problems/0647.回文子串.md +++ b/problems/0647.回文子串.md @@ -361,7 +361,51 @@ func countSubstrings(s string) int { } ``` +Javascript +> 动态规划 +```javascript +const countSubstrings = (s) => { + const strLen = s.length; + let numOfPalindromicStr = 0; + let dp = Array.from(Array(strLen), () => Array(strLen).fill(false)); + for(let j = 0; j < strLen; j++) { + for(let i = 0; i <= j; i++) { + if(s[i] === s[j]) { + if((j - i) < 2) { + dp[i][j] = true; + } else { + dp[i][j] = dp[i+1][j-1]; + } + numOfPalindromicStr += dp[i][j] ? 1 : 0; + } + } + } + + return numOfPalindromicStr; +} +``` + +> 双指针法: +```javascript +const countSubstrings = (s) => { + const strLen = s.length; + let numOfPalindromicStr = 0; + + for(let i = 0; i < 2 * strLen - 1; i++) { + let left = Math.floor(i/2); + let right = left + i % 2; + + while(left >= 0 && right < strLen && s[left] === s[right]){ + numOfPalindromicStr++; + left--; + right++; + } + } + + return numOfPalindromicStr; +} +``` ----------------------- diff --git a/problems/0674.最长连续递增序列.md b/problems/0674.最长连续递增序列.md index 31ab6b0e..614bff72 100644 --- a/problems/0674.最长连续递增序列.md +++ b/problems/0674.最长连续递增序列.md @@ -218,6 +218,49 @@ class Solution: Go: +Javascript: + +> 动态规划: +```javascript +const findLengthOfLCIS = (nums) => { + let dp = Array(nums.length).fill(1); + + + for(let i = 0; i < nums.length - 1; i++) { + if(nums[i+1] > nums[i]) { + dp[i+1] = dp[i]+ 1; + } + } + + return Math.max(...dp); +}; +``` + +> 贪心法: +```javascript +const findLengthOfLCIS = (nums) => { + if(nums.length === 1) { + return 1; + } + + let maxLen = 1; + let curMax = 1; + let cur = nums[0]; + + for(let num of nums) { + if(num > cur) { + curMax += 1; + maxLen = Math.max(maxLen, curMax); + } else { + curMax = 1; + } + cur = num; + } + + return maxLen; +}; +``` + diff --git a/problems/1005.K次取反后最大化的数组和.md b/problems/1005.K次取反后最大化的数组和.md index c3e99f7e..3534e1e2 100644 --- a/problems/1005.K次取反后最大化的数组和.md +++ b/problems/1005.K次取反后最大化的数组和.md @@ -99,6 +99,33 @@ public: Java: +```java +class Solution { + public int largestSumAfterKNegations(int[] nums, int K) { + // 将数组按照绝对值大小从大到小排序,注意要按照绝对值的大小 + nums = IntStream.of(nums) + .boxed() + .sorted((o1, o2) -> Math.abs(o2) - Math.abs(o1)) + .mapToInt(Integer::intValue).toArray(); + int len = nums.length; + for (int i = 0; i < len; i++) { + //从前向后遍历,遇到负数将其变为正数,同时K-- + if (nums[i] < 0 && k > 0) { + nums[i] = -nums[i]; + k--; + } + } + // 如果K还大于0,那么反复转变数值最小的元素,将K用完 + if (k % 2 == 1) nums[len - 1] = -nums[len - 1]; + int result = 0; + for (int a : nums) { + result += a; + } + return result; + } +} +``` + ```java class Solution { public int largestSumAfterKNegations(int[] A, int K) { diff --git a/problems/1143.最长公共子序列.md b/problems/1143.最长公共子序列.md index 8e245c20..e1fc1abb 100644 --- a/problems/1143.最长公共子序列.md +++ b/problems/1143.最长公共子序列.md @@ -197,7 +197,24 @@ func max(a,b int)int { } ``` +Javascript: +```javascript +const longestCommonSubsequence = (text1, text2) => { + let dp = Array.from(Array(text1.length+1), () => Array(text2.length+1).fill(0)); + for(let i = 1; i <= text1.length; i++) { + for(let j = 1; j <= text2.length; j++) { + if(text1[i-1] === text2[j-1]) { + dp[i][j] = dp[i-1][j-1] +1;; + } else { + dp[i][j] = Math.max(dp[i-1][j], dp[i][j-1]) + } + } + } + + return dp[text1.length][text2.length]; +}; +``` ----------------------- diff --git a/problems/前序/程序员写文档工具.md b/problems/前序/程序员写文档工具.md index 5530e30f..b06ce0ad 100644 --- a/problems/前序/程序员写文档工具.md +++ b/problems/前序/程序员写文档工具.md @@ -124,7 +124,7 @@ Markdown支持部分html,例如这样 我这里仅仅是介绍了几个常用的语法,刚开始学习Markdown的时候语法难免会忘。 -所以建议把这个markdown demo:https://markdown-it.github.io/收藏一下,平时用到哪里了忘了就看一看。 +所以建议把这个markdown demo:https://markdown-it.github.io/ 收藏一下,平时用到哪里了忘了就看一看。 就酱,后面我还会陆续给大家安利一些编程利器。