mirror of
https://github.com/youngyangyang04/leetcode-master.git
synced 2025-07-07 07:35:35 +08:00
Update
This commit is contained in:
@ -402,6 +402,38 @@ bool isValid(char * s){
|
||||
```
|
||||
|
||||
|
||||
C#:
|
||||
```csharp
|
||||
public class Solution {
|
||||
public bool IsValid(string s) {
|
||||
var len = s.Length;
|
||||
if(len % 2 == 1) return false; // 字符串长度为单数,直接返回 false
|
||||
// 初始化栈
|
||||
var stack = new Stack<char>();
|
||||
// 遍历字符串
|
||||
for(int i = 0; i < len; i++){
|
||||
// 当字符串为左括号时,进栈对应的右括号
|
||||
if(s[i] == '('){
|
||||
stack.Push(')');
|
||||
}else if(s[i] == '['){
|
||||
stack.Push(']');
|
||||
}else if(s[i] == '{'){
|
||||
stack.Push('}');
|
||||
}
|
||||
// 当字符串为右括号时,当栈为空(无左括号) 或者 出栈字符不是当前的字符
|
||||
else if(stack.Count == 0 || stack.Pop() != s[i])
|
||||
return false;
|
||||
}
|
||||
// 如果栈不为空,例如“((()”,右括号少于左括号,返回false
|
||||
if (stack.Count > 0)
|
||||
return false;
|
||||
// 上面的校验都满足,则返回true
|
||||
else
|
||||
return true;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
PHP:
|
||||
```php
|
||||
// https://www.php.net/manual/zh/class.splstack.php
|
||||
|
@ -116,6 +116,48 @@ class Solution {
|
||||
}
|
||||
}
|
||||
```
|
||||
> 优化时间复杂度为O(N),空间复杂度为O(1)
|
||||
```Java
|
||||
class Solution {
|
||||
public void nextPermutation(int[] nums) {
|
||||
// 1.从后向前获取逆序区域的前一位
|
||||
int index = findIndex(nums);
|
||||
// 判断数组是否处于最小组合状态
|
||||
if(index != 0){
|
||||
// 2.交换逆序区域刚好大于它的最小数字
|
||||
exchange(nums,index);
|
||||
}
|
||||
// 3.把原来的逆序区转为顺序
|
||||
reverse(nums,index);
|
||||
}
|
||||
|
||||
public static int findIndex(int [] nums){
|
||||
for(int i = nums.length-1;i>0;i--){
|
||||
if(nums[i]>nums[i-1]){
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
public static void exchange(int [] nums, int index){
|
||||
int head = nums[index-1];
|
||||
for(int i = nums.length-1;i>0;i--){
|
||||
if(head < nums[i]){
|
||||
nums[index-1] = nums[i];
|
||||
nums[i] = head;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
public static void reverse(int [] nums, int index){
|
||||
for(int i = index,j = nums.length-1;i<j;i++,j--){
|
||||
int temp = nums[i];
|
||||
nums[i] = nums[j];
|
||||
nums[j] = temp;
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Python
|
||||
>直接使用sorted()不符合题意
|
||||
@ -164,7 +206,7 @@ class Solution:
|
||||
high -= 1
|
||||
```
|
||||
>上一版本简化版
|
||||
'''python
|
||||
```python
|
||||
class Solution(object):
|
||||
def nextPermutation(self, nums: List[int]) -> None:
|
||||
n = len(nums)
|
||||
@ -185,7 +227,7 @@ class Solution(object):
|
||||
end -= 1
|
||||
|
||||
return nums
|
||||
'''
|
||||
```
|
||||
|
||||
## Go
|
||||
|
||||
|
@ -142,7 +142,7 @@ public:
|
||||
```
|
||||
|
||||
* 时间复杂度:O(log n)
|
||||
* 时间复杂度:O(1)
|
||||
* 空间复杂度:O(1)
|
||||
|
||||
效率如下:
|
||||

|
||||
|
@ -417,6 +417,35 @@ function combinationSum(candidates: number[], target: number): number[][] {
|
||||
};
|
||||
```
|
||||
|
||||
## Rust
|
||||
|
||||
```Rust
|
||||
impl Solution {
|
||||
pub fn backtracking(result: &mut Vec<Vec<i32>>, path: &mut Vec<i32>, candidates: &Vec<i32>, target: i32, mut sum: i32, start_index: usize) {
|
||||
if sum == target {
|
||||
result.push(path.to_vec());
|
||||
return;
|
||||
}
|
||||
for i in start_index..candidates.len() {
|
||||
if sum + candidates[i] <= target {
|
||||
sum += candidates[i];
|
||||
path.push(candidates[i]);
|
||||
Self::backtracking(result, path, candidates, target, sum, i);
|
||||
sum -= candidates[i];
|
||||
path.pop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn combination_sum(candidates: Vec<i32>, target: i32) -> Vec<Vec<i32>> {
|
||||
let mut result: Vec<Vec<i32>> = Vec::new();
|
||||
let mut path: Vec<i32> = Vec::new();
|
||||
Self::backtracking(&mut result, &mut path, &candidates, target, 0, 0);
|
||||
result
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## C
|
||||
|
||||
```c
|
||||
|
@ -599,6 +599,41 @@ function combinationSum2(candidates: number[], target: number): number[][] {
|
||||
};
|
||||
```
|
||||
|
||||
## Rust
|
||||
|
||||
```Rust
|
||||
impl Solution {
|
||||
pub fn backtracking(result: &mut Vec<Vec<i32>>, path: &mut Vec<i32>, candidates: &Vec<i32>, target: i32, mut sum: i32, start_index: usize, used: &mut Vec<bool>) {
|
||||
if sum == target {
|
||||
result.push(path.to_vec());
|
||||
return;
|
||||
}
|
||||
for i in start_index..candidates.len() {
|
||||
if sum + candidates[i] <= target {
|
||||
if i > 0 && candidates[i] == candidates[i - 1] && used[i - 1] == false { continue; }
|
||||
sum += candidates[i];
|
||||
path.push(candidates[i]);
|
||||
used[i] = true;
|
||||
Self::backtracking(result, path, candidates, target, sum, i + 1, used);
|
||||
used[i] = false;
|
||||
sum -= candidates[i];
|
||||
path.pop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn combination_sum2(candidates: Vec<i32>, target: i32) -> Vec<Vec<i32>> {
|
||||
let mut result: Vec<Vec<i32>> = Vec::new();
|
||||
let mut path: Vec<i32> = Vec::new();
|
||||
let mut used: Vec<bool> = vec![false; candidates.len()];
|
||||
let mut candidates = candidates;
|
||||
candidates.sort();
|
||||
Self::backtracking(&mut result, &mut path, &candidates, target, 0, 0, &mut used);
|
||||
result
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## C
|
||||
|
||||
```c
|
||||
|
@ -297,7 +297,37 @@ function merge(intervals: number[][]): number[][] {
|
||||
};
|
||||
```
|
||||
|
||||
### Scala
|
||||
|
||||
```scala
|
||||
object Solution {
|
||||
import scala.collection.mutable
|
||||
def merge(intervals: Array[Array[Int]]): Array[Array[Int]] = {
|
||||
var res = mutable.ArrayBuffer[Array[Int]]()
|
||||
|
||||
// 排序
|
||||
var interval = intervals.sortWith((a, b) => {
|
||||
a(0) < b(0)
|
||||
})
|
||||
|
||||
var left = interval(0)(0)
|
||||
var right = interval(0)(1)
|
||||
|
||||
for (i <- 1 until interval.length) {
|
||||
if (interval(i)(0) <= right) {
|
||||
left = math.min(left, interval(i)(0))
|
||||
right = math.max(right, interval(i)(1))
|
||||
} else {
|
||||
res.append(Array[Int](left, right))
|
||||
left = interval(i)(0)
|
||||
right = interval(i)(1)
|
||||
}
|
||||
}
|
||||
res.append(Array[Int](left, right))
|
||||
res.toArray // 返回res的Array形式
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
-----------------------
|
||||
<div align="center"><img src=https://code-thinking.cdn.bcebos.com/pics/01二维码一.jpg width=500> </img></div>
|
||||
|
@ -598,5 +598,30 @@ object Solution {
|
||||
}
|
||||
}
|
||||
```
|
||||
C#:
|
||||
```csharp
|
||||
public class Solution {
|
||||
public int[][] GenerateMatrix(int n) {
|
||||
int[][] answer = new int[n][];
|
||||
for(int i = 0; i < n; i++)
|
||||
answer[i] = new int[n];
|
||||
int start = 0;
|
||||
int end = n - 1;
|
||||
int tmp = 1;
|
||||
while(tmp < n * n)
|
||||
{
|
||||
for(int i = start; i < end; i++) answer[start][i] = tmp++;
|
||||
for(int i = start; i < end; i++) answer[i][end] = tmp++;
|
||||
for(int i = end; i > start; i--) answer[end][i] = tmp++;
|
||||
for(int i = end; i > start; i--) answer[i][start] = tmp++;
|
||||
start++;
|
||||
end--;
|
||||
}
|
||||
if(n % 2 == 1) answer[n / 2][n / 2] = tmp;
|
||||
return answer;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
-----------------------
|
||||
<div align="center"><img src=https://code-thinking.cdn.bcebos.com/pics/01二维码一.jpg width=500> </img></div>
|
||||
|
@ -436,5 +436,21 @@ int uniquePaths(int m, int n){
|
||||
}
|
||||
```
|
||||
|
||||
### Scala
|
||||
|
||||
```scala
|
||||
object Solution {
|
||||
def uniquePaths(m: Int, n: Int): Int = {
|
||||
var dp = Array.ofDim[Int](m, n)
|
||||
for (i <- 0 until m) dp(i)(0) = 1
|
||||
for (j <- 1 until n) dp(0)(j) = 1
|
||||
for (i <- 1 until m; j <- 1 until n) {
|
||||
dp(i)(j) = dp(i - 1)(j) + dp(i)(j - 1)
|
||||
}
|
||||
dp(m - 1)(n - 1)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
-----------------------
|
||||
<div align="center"><img src=https://code-thinking.cdn.bcebos.com/pics/01二维码一.jpg width=500> </img></div>
|
||||
|
@ -476,5 +476,37 @@ int uniquePathsWithObstacles(int** obstacleGrid, int obstacleGridSize, int* obst
|
||||
}
|
||||
```
|
||||
|
||||
### Scala
|
||||
|
||||
```scala
|
||||
object Solution {
|
||||
import scala.util.control.Breaks._
|
||||
def uniquePathsWithObstacles(obstacleGrid: Array[Array[Int]]): Int = {
|
||||
var (m, n) = (obstacleGrid.length, obstacleGrid(0).length)
|
||||
var dp = Array.ofDim[Int](m, n)
|
||||
|
||||
// 比如break、continue这些流程控制需要使用breakable
|
||||
breakable(
|
||||
for (i <- 0 until m) {
|
||||
if (obstacleGrid(i)(0) != 1) dp(i)(0) = 1
|
||||
else break()
|
||||
}
|
||||
)
|
||||
breakable(
|
||||
for (j <- 0 until n) {
|
||||
if (obstacleGrid(0)(j) != 1) dp(0)(j) = 1
|
||||
else break()
|
||||
}
|
||||
)
|
||||
|
||||
for (i <- 1 until m; j <- 1 until n; if obstacleGrid(i)(j) != 1) {
|
||||
dp(i)(j) = dp(i - 1)(j) + dp(i)(j - 1)
|
||||
}
|
||||
|
||||
dp(m - 1)(n - 1)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
-----------------------
|
||||
<div align="center"><img src=https://code-thinking.cdn.bcebos.com/pics/01二维码一.jpg width=500> </img></div>
|
||||
|
@ -401,6 +401,38 @@ int climbStairs(int n){
|
||||
}
|
||||
```
|
||||
|
||||
### Scala
|
||||
|
||||
```scala
|
||||
object Solution {
|
||||
def climbStairs(n: Int): Int = {
|
||||
if (n <= 2) return n
|
||||
var dp = new Array[Int](n + 1)
|
||||
dp(1) = 1
|
||||
dp(2) = 2
|
||||
for (i <- 3 to n) {
|
||||
dp(i) = dp(i - 1) + dp(i - 2)
|
||||
}
|
||||
dp(n)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
优化空间复杂度:
|
||||
```scala
|
||||
object Solution {
|
||||
def climbStairs(n: Int): Int = {
|
||||
if (n <= 2) return n
|
||||
var (a, b) = (1, 2)
|
||||
for (i <- 3 to n) {
|
||||
var tmp = a + b
|
||||
a = b
|
||||
b = tmp
|
||||
}
|
||||
b // 最终返回b
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
-----------------------
|
||||
<div align="center"><img src=https://code-thinking.cdn.bcebos.com/pics/01二维码一.jpg width=500> </img></div>
|
||||
|
@ -261,6 +261,33 @@ class Solution:
|
||||
self.path.pop()
|
||||
```
|
||||
|
||||
### Python3
|
||||
```python3
|
||||
class Solution:
|
||||
def subsetsWithDup(self, nums: List[int]) -> List[List[int]]:
|
||||
res = []
|
||||
path = []
|
||||
nums.sort() # 去重需要先对数组进行排序
|
||||
|
||||
def backtracking(nums, startIndex):
|
||||
# 终止条件
|
||||
res.append(path[:])
|
||||
if startIndex == len(nums):
|
||||
return
|
||||
|
||||
# for循环
|
||||
for i in range(startIndex, len(nums)):
|
||||
# 数层去重
|
||||
if i > startIndex and nums[i] == nums[i-1]: # 去重
|
||||
continue
|
||||
path.append(nums[i])
|
||||
backtracking(nums, i+1)
|
||||
path.pop()
|
||||
|
||||
backtracking(nums, 0)
|
||||
return res
|
||||
```
|
||||
|
||||
### Go
|
||||
|
||||
```Go
|
||||
|
@ -227,7 +227,7 @@ const numTrees =(n) => {
|
||||
};
|
||||
```
|
||||
|
||||
TypeScript
|
||||
### TypeScript
|
||||
|
||||
```typescript
|
||||
function numTrees(n: number): number {
|
||||
@ -282,5 +282,22 @@ int numTrees(int n){
|
||||
}
|
||||
```
|
||||
|
||||
### Scala
|
||||
|
||||
```scala
|
||||
object Solution {
|
||||
def numTrees(n: Int): Int = {
|
||||
var dp = new Array[Int](n + 1)
|
||||
dp(0) = 1
|
||||
for (i <- 1 to n) {
|
||||
for (j <- 1 to i) {
|
||||
dp(i) += dp(j - 1) * dp(i - j)
|
||||
}
|
||||
}
|
||||
dp(n)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
-----------------------
|
||||
<div align="center"><img src=https://code-thinking.cdn.bcebos.com/pics/01二维码一.jpg width=500> </img></div>
|
||||
|
@ -372,7 +372,7 @@ var minDepth1 = function(root) {
|
||||
// 到叶子节点 返回 1
|
||||
if(!root.left && !root.right) return 1;
|
||||
// 只有右节点时 递归右节点
|
||||
if(!root.left) return 1 + minDepth(root.right);、
|
||||
if(!root.left) return 1 + minDepth(root.right);
|
||||
// 只有左节点时 递归左节点
|
||||
if(!root.right) return 1 + minDepth(root.left);
|
||||
return Math.min(minDepth(root.left), minDepth(root.right)) + 1;
|
||||
|
@ -626,7 +626,8 @@ func partition(_ s: String) -> [[String]] {
|
||||
|
||||
## Rust
|
||||
|
||||
```rust
|
||||
**回溯+函数判断回文串**
|
||||
```Rust
|
||||
impl Solution {
|
||||
pub fn partition(s: String) -> Vec<Vec<String>> {
|
||||
let mut ret = vec![];
|
||||
@ -676,6 +677,40 @@ impl Solution {
|
||||
}
|
||||
}
|
||||
```
|
||||
**回溯+动态规划预处理判断回文串**
|
||||
```Rust
|
||||
impl Solution {
|
||||
pub fn backtracking(is_palindrome: &Vec<Vec<bool>>, result: &mut Vec<Vec<String>>, path: &mut Vec<String>, s: &Vec<char>, start_index: usize) {
|
||||
let len = s.len();
|
||||
if start_index >= len {
|
||||
result.push(path.to_vec());
|
||||
return;
|
||||
}
|
||||
for i in start_index..len {
|
||||
if is_palindrome[start_index][i] { path.push(s[start_index..=i].iter().collect::<String>()); } else { continue; }
|
||||
Self::backtracking(is_palindrome, result, path, s, i + 1);
|
||||
path.pop();
|
||||
}
|
||||
}
|
||||
|
||||
pub fn partition(s: String) -> Vec<Vec<String>> {
|
||||
let mut result: Vec<Vec<String>> = Vec::new();
|
||||
let mut path: Vec<String> = Vec::new();
|
||||
let s = s.chars().collect::<Vec<char>>();
|
||||
let len: usize = s.len();
|
||||
// 使用动态规划预先打表
|
||||
// 当且仅当其为空串(i>j),或其长度为1(i=j),或者首尾字符相同且(s[i+1..j−1])时为回文串
|
||||
let mut is_palindrome = vec![vec![true; len]; len];
|
||||
for i in (0..len).rev() {
|
||||
for j in (i + 1)..len {
|
||||
is_palindrome[i][j] = s[i] == s[j] && is_palindrome[i + 1][j - 1];
|
||||
}
|
||||
}
|
||||
Self::backtracking(&is_palindrome, &mut result, &mut path, &s, 0);
|
||||
result
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
## Scala
|
||||
|
@ -324,6 +324,31 @@ function candy(ratings: number[]): number {
|
||||
};
|
||||
```
|
||||
|
||||
### Scala
|
||||
|
||||
```scala
|
||||
object Solution {
|
||||
def candy(ratings: Array[Int]): Int = {
|
||||
var candyVec = new Array[Int](ratings.length)
|
||||
for (i <- candyVec.indices) candyVec(i) = 1
|
||||
// 从前向后
|
||||
for (i <- 1 until candyVec.length) {
|
||||
if (ratings(i) > ratings(i - 1)) {
|
||||
candyVec(i) = candyVec(i - 1) + 1
|
||||
}
|
||||
}
|
||||
|
||||
// 从后向前
|
||||
for (i <- (candyVec.length - 2) to 0 by -1) {
|
||||
if (ratings(i) > ratings(i + 1)) {
|
||||
candyVec(i) = math.max(candyVec(i), candyVec(i + 1) + 1)
|
||||
}
|
||||
}
|
||||
|
||||
candyVec.sum // 求和
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
-----------------------
|
||||
|
@ -326,6 +326,40 @@ func evalRPN(_ tokens: [String]) -> Int {
|
||||
}
|
||||
```
|
||||
|
||||
C#:
|
||||
```csharp
|
||||
public int EvalRPN(string[] tokens) {
|
||||
int num;
|
||||
Stack<int> stack = new Stack<int>();
|
||||
foreach(string s in tokens){
|
||||
if(int.TryParse(s, out num)){
|
||||
stack.Push(num);
|
||||
}else{
|
||||
int num1 = stack.Pop();
|
||||
int num2 = stack.Pop();
|
||||
switch (s)
|
||||
{
|
||||
case "+":
|
||||
stack.Push(num1 + num2);
|
||||
break;
|
||||
case "-":
|
||||
stack.Push(num2 - num1);
|
||||
break;
|
||||
case "*":
|
||||
stack.Push(num1 * num2);
|
||||
break;
|
||||
case "/":
|
||||
stack.Push(num2 / num1);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return stack.Pop();
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
PHP:
|
||||
```php
|
||||
|
@ -900,6 +900,41 @@ class MyStack() {
|
||||
```
|
||||
|
||||
|
||||
C#:
|
||||
```csharp
|
||||
public class MyStack {
|
||||
Queue<int> queue1;
|
||||
Queue<int> queue2;
|
||||
public MyStack() {
|
||||
queue1 = new Queue<int>();
|
||||
queue2 = new Queue<int>();
|
||||
}
|
||||
|
||||
public void Push(int x) {
|
||||
queue2.Enqueue(x);
|
||||
while(queue1.Count != 0){
|
||||
queue2.Enqueue(queue1.Dequeue());
|
||||
}
|
||||
Queue<int> queueTemp;
|
||||
queueTemp = queue1;
|
||||
queue1 = queue2;
|
||||
queue2 = queueTemp;
|
||||
}
|
||||
|
||||
public int Pop() {
|
||||
return queue1.Count > 0 ? queue1.Dequeue() : -1;
|
||||
}
|
||||
|
||||
public int Top() {
|
||||
return queue1.Count > 0 ? queue1.Peek() : -1;
|
||||
}
|
||||
|
||||
public bool Empty() {
|
||||
return queue1.Count == 0;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
PHP
|
||||
> 双对列
|
||||
```php
|
||||
|
@ -497,6 +497,49 @@ void myQueueFree(MyQueue* obj) {
|
||||
```
|
||||
|
||||
|
||||
C#:
|
||||
```csharp
|
||||
public class MyQueue {
|
||||
Stack<int> inStack;
|
||||
Stack<int> outStack;
|
||||
|
||||
public MyQueue() {
|
||||
inStack = new Stack<int>();// 负责进栈
|
||||
outStack = new Stack<int>();// 负责出栈
|
||||
}
|
||||
|
||||
public void Push(int x) {
|
||||
inStack.Push(x);
|
||||
}
|
||||
|
||||
public int Pop() {
|
||||
dumpstackIn();
|
||||
return outStack.Pop();
|
||||
}
|
||||
|
||||
public int Peek() {
|
||||
dumpstackIn();
|
||||
return outStack.Peek();
|
||||
}
|
||||
|
||||
public bool Empty() {
|
||||
return inStack.Count == 0 && outStack.Count == 0;
|
||||
}
|
||||
|
||||
// 处理方法:
|
||||
// 如果outStack为空,那么将inStack中的元素全部放到outStack中
|
||||
private void dumpstackIn(){
|
||||
if (outStack.Count != 0) return;
|
||||
while(inStack.Count != 0){
|
||||
outStack.Push(inStack.Pop());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
|
||||
|
||||
PHP:
|
||||
```php
|
||||
// SplStack 类通过使用一个双向链表来提供栈的主要功能。[PHP 5 >= 5.3.0, PHP 7, PHP 8]
|
||||
@ -583,5 +626,6 @@ class MyQueue() {
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
-----------------------
|
||||
<div align="center"><img src=https://code-thinking.cdn.bcebos.com/pics/01二维码一.jpg width=500> </img></div>
|
||||
|
@ -258,7 +258,75 @@ class Solution:
|
||||
### Go
|
||||
|
||||
```go
|
||||
/**
|
||||
* Definition for singly-linked list.
|
||||
* type ListNode struct {
|
||||
* Val int
|
||||
* Next *ListNode
|
||||
* }
|
||||
*/
|
||||
//方法一,使用数组
|
||||
func isPalindrome(head *ListNode) bool{
|
||||
//计算切片长度,避免切片频繁扩容
|
||||
cur,ln:=head,0
|
||||
for cur!=nil{
|
||||
ln++
|
||||
cur=cur.Next
|
||||
}
|
||||
nums:=make([]int,ln)
|
||||
index:=0
|
||||
for head!=nil{
|
||||
nums[index]=head.Val
|
||||
index++
|
||||
head=head.Next
|
||||
}
|
||||
//比较回文切片
|
||||
for i,j:=0,ln-1;i<=j;i,j=i+1,j-1{
|
||||
if nums[i]!=nums[j]{return false}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// 方法二,快慢指针
|
||||
func isPalindrome(head *ListNode) bool {
|
||||
if head==nil&&head.Next==nil{return true}
|
||||
//慢指针,找到链表中间分位置,作为分割
|
||||
slow:=head
|
||||
fast:=head
|
||||
//记录慢指针的前一个节点,用来分割链表
|
||||
pre:=head
|
||||
for fast!=nil && fast.Next!=nil{
|
||||
pre=slow
|
||||
slow=slow.Next
|
||||
fast=fast.Next.Next
|
||||
}
|
||||
//分割链表
|
||||
pre.Next=nil
|
||||
//前半部分
|
||||
cur1:=head
|
||||
//反转后半部分,总链表长度如果是奇数,cur2比cur1多一个节点
|
||||
cur2:=ReverseList(slow)
|
||||
|
||||
//开始两个链表的比较
|
||||
for cur1!=nil{
|
||||
if cur1.Val!=cur2.Val{return false}
|
||||
cur1=cur1.Next
|
||||
cur2=cur2.Next
|
||||
}
|
||||
return true
|
||||
}
|
||||
//反转链表
|
||||
func ReverseList(head *ListNode) *ListNode{
|
||||
var pre *ListNode
|
||||
cur:=head
|
||||
for cur!=nil{
|
||||
tmp:=cur.Next
|
||||
cur.Next=pre
|
||||
pre=cur
|
||||
cur=tmp
|
||||
}
|
||||
return pre
|
||||
}
|
||||
```
|
||||
|
||||
### JavaScript
|
||||
|
@ -756,5 +756,46 @@ class MyQueue{
|
||||
}
|
||||
```
|
||||
|
||||
C#:
|
||||
```csharp
|
||||
class myDequeue{
|
||||
private LinkedList<int> linkedList = new LinkedList<int>();
|
||||
|
||||
public void Enqueue(int n){
|
||||
while(linkedList.Count > 0 && linkedList.Last.Value < n){
|
||||
linkedList.RemoveLast();
|
||||
}
|
||||
linkedList.AddLast(n);
|
||||
}
|
||||
|
||||
public int Max(){
|
||||
return linkedList.First.Value;
|
||||
}
|
||||
|
||||
public void Dequeue(int n){
|
||||
if(linkedList.First.Value == n){
|
||||
linkedList.RemoveFirst();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
myDequeue window = new myDequeue();
|
||||
List<int> res = new List<int>();
|
||||
|
||||
public int[] MaxSlidingWindow(int[] nums, int k) {
|
||||
for(int i = 0; i < k; i++){
|
||||
window.Enqueue(nums[i]);
|
||||
}
|
||||
res.Add(window.Max());
|
||||
for(int i = k; i < nums.Length; i++){
|
||||
window.Dequeue(nums[i-k]);
|
||||
window.Enqueue(nums[i]);
|
||||
res.Add(window.Max());
|
||||
}
|
||||
|
||||
return res.ToArray();
|
||||
}
|
||||
```
|
||||
|
||||
-----------------------
|
||||
<div align="center"><img src=https://code-thinking.cdn.bcebos.com/pics/01二维码一.jpg width=500> </img></div>
|
||||
|
@ -127,8 +127,6 @@ class Solution:
|
||||
if record[i] != 0:
|
||||
#record数组如果有的元素不为零0,说明字符串s和t 一定是谁多了字符或者谁少了字符。
|
||||
return False
|
||||
#如果有一个元素不为零,则可以判断字符串s和t不是字母异位词
|
||||
break
|
||||
return True
|
||||
```
|
||||
|
||||
|
@ -44,6 +44,8 @@ dp[i][j],第i天状态为j,所剩的最多现金为dp[i][j]。
|
||||
* 状态三:今天卖出了股票
|
||||
* 状态四:今天为冷冻期状态,但冷冻期状态不可持续,只有一天!
|
||||
|
||||

|
||||
|
||||
j的状态为:
|
||||
|
||||
* 0:状态一
|
||||
@ -57,7 +59,7 @@ j的状态为:
|
||||
|
||||
**注意这里的每一个状态,例如状态一,是买入股票状态并不是说今天已经就买入股票,而是说保存买入股票的状态即:可能是前几天买入的,之后一直没操作,所以保持买入股票的状态**。
|
||||
|
||||
2. 确定递推公式
|
||||
1. 确定递推公式
|
||||
|
||||
|
||||
达到买入股票状态(状态一)即:dp[i][0],有两个具体操作:
|
||||
|
@ -335,5 +335,22 @@ int integerBreak(int n){
|
||||
}
|
||||
```
|
||||
|
||||
### Scala
|
||||
|
||||
```scala
|
||||
object Solution {
|
||||
def integerBreak(n: Int): Int = {
|
||||
var dp = new Array[Int](n + 1)
|
||||
dp(2) = 1
|
||||
for (i <- 3 to n) {
|
||||
for (j <- 1 until i - 1) {
|
||||
dp(i) = math.max(dp(i), math.max(j * (i - j), j * dp(i - j)))
|
||||
}
|
||||
}
|
||||
dp(n)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
-----------------------
|
||||
<div align="center"><img src=https://code-thinking.cdn.bcebos.com/pics/01二维码一.jpg width=500> </img></div>
|
||||
|
@ -371,6 +371,44 @@ function topKFrequent(nums: number[], k: number): number[] {
|
||||
};
|
||||
```
|
||||
|
||||
C#:
|
||||
```csharp
|
||||
public int[] TopKFrequent(int[] nums, int k) {
|
||||
//哈希表-标权重
|
||||
Dictionary<int,int> dic = new();
|
||||
for(int i = 0; i < nums.Length; i++){
|
||||
if(dic.ContainsKey(nums[i])){
|
||||
dic[nums[i]]++;
|
||||
}else{
|
||||
dic.Add(nums[i], 1);
|
||||
}
|
||||
}
|
||||
//优先队列-从小到大排列
|
||||
PriorityQueue<int,int> pq = new();
|
||||
foreach(var num in dic){
|
||||
pq.Enqueue(num.Key, num.Value);
|
||||
if(pq.Count > k){
|
||||
pq.Dequeue();
|
||||
}
|
||||
}
|
||||
|
||||
// //Stack-倒置
|
||||
// Stack<int> res = new();
|
||||
// while(pq.Count > 0){
|
||||
// res.Push(pq.Dequeue());
|
||||
// }
|
||||
// return res.ToArray();
|
||||
|
||||
//数组倒装
|
||||
int[] res = new int[k];
|
||||
for(int i = k - 1; i >= 0; i--){
|
||||
res[i] = pq.Dequeue();
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
Scala:
|
||||
|
||||
解法一: 优先级队列
|
||||
@ -413,6 +451,7 @@ object Solution {
|
||||
.map(_._1)
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
-----------------------
|
||||
|
@ -354,8 +354,27 @@ function reconstructQueue(people: number[][]): number[][] {
|
||||
};
|
||||
```
|
||||
|
||||
### Scala
|
||||
|
||||
```scala
|
||||
object Solution {
|
||||
import scala.collection.mutable
|
||||
def reconstructQueue(people: Array[Array[Int]]): Array[Array[Int]] = {
|
||||
val person = people.sortWith((a, b) => {
|
||||
if (a(0) == b(0)) a(1) < b(1)
|
||||
else a(0) > b(0)
|
||||
})
|
||||
|
||||
var que = mutable.ArrayBuffer[Array[Int]]()
|
||||
|
||||
for (per <- person) {
|
||||
que.insert(per(1), per)
|
||||
}
|
||||
|
||||
que.toArray
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
-----------------------
|
||||
|
@ -183,7 +183,7 @@ public:
|
||||
## 其他语言版本
|
||||
|
||||
|
||||
Java:
|
||||
### Java:
|
||||
```Java
|
||||
class Solution {
|
||||
public boolean canPartition(int[] nums) {
|
||||
@ -316,7 +316,7 @@ class Solution {
|
||||
}
|
||||
}
|
||||
```
|
||||
Python:
|
||||
### Python:
|
||||
```python
|
||||
class Solution:
|
||||
def canPartition(self, nums: List[int]) -> bool:
|
||||
@ -329,7 +329,7 @@ class Solution:
|
||||
dp[j] = max(dp[j], dp[j - nums[i]] + nums[i])
|
||||
return target == dp[target]
|
||||
```
|
||||
Go:
|
||||
### Go:
|
||||
```go
|
||||
// 分割等和子集 动态规划
|
||||
// 时间复杂度O(n^2) 空间复杂度O(n)
|
||||
@ -397,7 +397,7 @@ func canPartition(nums []int) bool {
|
||||
}
|
||||
```
|
||||
|
||||
javaScript:
|
||||
### javaScript:
|
||||
|
||||
```js
|
||||
var canPartition = function(nums) {
|
||||
@ -417,27 +417,11 @@ var canPartition = function(nums) {
|
||||
```
|
||||
|
||||
|
||||
TypeScript:
|
||||
|
||||
```ts
|
||||
function canPartition(nums: number[]): boolean {
|
||||
const sum: number = nums.reduce((a: number, b: number): number => a + b);
|
||||
if (sum % 2 === 1) return false;
|
||||
const target: number = sum / 2;
|
||||
// dp[j]表示容量(总数和)为j的背包所能装下的数(下标[0, i]之间任意取)的总和(<= 容量)的最大值
|
||||
const dp: number[] = new Array(target + 1).fill(0);
|
||||
const n: number = nums.length;
|
||||
for (let i: number = 0; i < n; i++) {
|
||||
for (let j: number = target; j >= nums[i]; j--) {
|
||||
dp[j] = Math.max(dp[j], dp[j - nums[i]] + nums[i]);
|
||||
}
|
||||
}
|
||||
return dp[target] === target;
|
||||
};
|
||||
```
|
||||
|
||||
|
||||
C:
|
||||
|
||||
### C:
|
||||
|
||||
二维dp:
|
||||
```c
|
||||
/**
|
||||
@ -538,7 +522,7 @@ bool canPartition(int* nums, int numsSize){
|
||||
}
|
||||
```
|
||||
|
||||
TypeScript:
|
||||
### TypeScript:
|
||||
|
||||
> 一维数组,简洁
|
||||
|
||||
@ -593,7 +577,50 @@ function canPartition(nums: number[]): boolean {
|
||||
};
|
||||
```
|
||||
|
||||
### Scala
|
||||
|
||||
滚动数组:
|
||||
```scala
|
||||
object Solution {
|
||||
def canPartition(nums: Array[Int]): Boolean = {
|
||||
var sum = nums.sum
|
||||
if (sum % 2 != 0) return false
|
||||
var half = sum / 2
|
||||
var dp = new Array[Int](half + 1)
|
||||
|
||||
// 遍历
|
||||
for (i <- 0 until nums.length; j <- half to nums(i) by -1) {
|
||||
dp(j) = math.max(dp(j), dp(j - nums(i)) + nums(i))
|
||||
}
|
||||
|
||||
if (dp(half) == half) true else false
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
二维数组:
|
||||
```scala
|
||||
object Solution {
|
||||
def canPartition(nums: Array[Int]): Boolean = {
|
||||
var sum = nums.sum
|
||||
if (sum % 2 != 0) return false
|
||||
var half = sum / 2
|
||||
var dp = Array.ofDim[Int](nums.length, half + 1)
|
||||
|
||||
// 初始化
|
||||
for (j <- nums(0) to half) dp(0)(j) = nums(0)
|
||||
|
||||
// 遍历
|
||||
for (i <- 1 until nums.length; j <- 1 to half) {
|
||||
if (j - nums(i) >= 0) dp(i)(j) = nums(i) + dp(i - 1)(j - nums(i))
|
||||
dp(i)(j) = math.max(dp(i)(j), dp(i - 1)(j))
|
||||
}
|
||||
|
||||
// 如果等于half就返回ture,否则返回false
|
||||
if (dp(nums.length - 1)(half) == half) true else false
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
-----------------------
|
||||
<div align="center"><img src=https://code-thinking.cdn.bcebos.com/pics/01二维码一.jpg width=500> </img></div>
|
||||
|
@ -352,7 +352,27 @@ function eraseOverlapIntervals(intervals: number[][]): number {
|
||||
};
|
||||
```
|
||||
|
||||
### Scala
|
||||
|
||||
```scala
|
||||
object Solution {
|
||||
def eraseOverlapIntervals(intervals: Array[Array[Int]]): Int = {
|
||||
var result = 0
|
||||
var interval = intervals.sortWith((a, b) => {
|
||||
a(1) < b(1)
|
||||
})
|
||||
var edge = Int.MinValue
|
||||
for (i <- 0 until interval.length) {
|
||||
if (edge <= interval(i)(0)) {
|
||||
edge = interval(i)(1)
|
||||
} else {
|
||||
result += 1
|
||||
}
|
||||
}
|
||||
result
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
@ -322,33 +322,25 @@ class Solution {
|
||||
|
||||
```python
|
||||
class Solution:
|
||||
def deleteNode(self, root: TreeNode, key: int) -> TreeNode:
|
||||
if not root: return root #第一种情况:没找到删除的节点,遍历到空节点直接返回了
|
||||
if root.val == key:
|
||||
if not root.left and not root.right: #第二种情况:左右孩子都为空(叶子节点),直接删除节点, 返回NULL为根节点
|
||||
del root
|
||||
return None
|
||||
if not root.left and root.right: #第三种情况:其左孩子为空,右孩子不为空,删除节点,右孩子补位 ,返回右孩子为根节点
|
||||
tmp = root
|
||||
root = root.right
|
||||
del tmp
|
||||
return root
|
||||
if root.left and not root.right: #第四种情况:其右孩子为空,左孩子不为空,删除节点,左孩子补位,返回左孩子为根节点
|
||||
tmp = root
|
||||
root = root.left
|
||||
del tmp
|
||||
return root
|
||||
else: #第五种情况:左右孩子节点都不为空,则将删除节点的左子树放到删除节点的右子树的最左面节点的左孩子的位置
|
||||
v = root.right
|
||||
while v.left:
|
||||
v = v.left
|
||||
v.left = root.left
|
||||
tmp = root
|
||||
root = root.right
|
||||
del tmp
|
||||
return root
|
||||
if root.val > key: root.left = self.deleteNode(root.left,key) #左递归
|
||||
if root.val < key: root.right = self.deleteNode(root.right,key) #右递归
|
||||
def deleteNode(self, root: Optional[TreeNode], key: int) -> Optional[TreeNode]:
|
||||
if not root : return None # 节点为空,返回
|
||||
if root.val < key :
|
||||
root.right = self.deleteNode(root.right, key)
|
||||
elif root.val > key :
|
||||
root.left = self.deleteNode(root.left, key)
|
||||
else:
|
||||
# 当前节点的左子树为空,返回当前的右子树
|
||||
if not root.left : return root.right
|
||||
# 当前节点的右子树为空,返回当前的左子树
|
||||
if not root.right: return root.left
|
||||
# 左右子树都不为空,找到右孩子的最左节点 记为p
|
||||
node = root.right
|
||||
while node.left :
|
||||
node = node.left
|
||||
# 将当前节点的左子树挂在p的左孩子上
|
||||
node.left = root.left
|
||||
# 当前节点的右子树替换掉当前节点,完成当前节点的删除
|
||||
root = root.right
|
||||
return root
|
||||
```
|
||||
|
||||
|
@ -151,6 +151,7 @@ class Solution {
|
||||
//重叠气球的最小右边界
|
||||
int leftmostRightBound = points[0][1];
|
||||
//如果下一个气球的左边界大于最小右边界
|
||||
for(int i = 1; i < points.length; i++){
|
||||
if (points[i][0] > leftmostRightBound ) {
|
||||
//增加一次射击
|
||||
count++;
|
||||
@ -299,5 +300,30 @@ impl Solution {
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Scala
|
||||
|
||||
```scala
|
||||
object Solution {
|
||||
def findMinArrowShots(points: Array[Array[Int]]): Int = {
|
||||
if (points.length == 0) return 0
|
||||
// 排序
|
||||
var point = points.sortWith((a, b) => {
|
||||
a(0) < b(0)
|
||||
})
|
||||
|
||||
var result = 1 // points不为空就至少需要一只箭
|
||||
for (i <- 1 until point.length) {
|
||||
if (point(i)(0) > point(i - 1)(1)) {
|
||||
result += 1
|
||||
} else {
|
||||
point(i)(1) = math.min(point(i - 1)(1), point(i)(1))
|
||||
}
|
||||
}
|
||||
result // 返回结果
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
-----------------------
|
||||
<div align="center"><img src=https://code-thinking.cdn.bcebos.com/pics/01二维码一.jpg width=500> </img></div>
|
||||
|
@ -134,7 +134,7 @@ next 数组记录的就是最长相同前后缀 [字符串:KMP算法精讲](ht
|
||||
|
||||
数组长度为:len。
|
||||
|
||||
如果len % (len - (next[len - 1] + 1)) == 0 ,则说明 (数组长度-最长相等前后缀的长度) 正好可以被 数组的长度整除,说明有该字符串有重复的子字符串。
|
||||
如果len % (len - (next[len - 1] + 1)) == 0 ,则说明数组的长度正好可以被 (数组长度-最长相等前后缀的长度) 整除 ,说明该字符串有重复的子字符串。
|
||||
|
||||
**数组长度减去最长相同前后缀的长度相当于是第一个周期的长度,也就是一个周期的长度,如果这个周期可以被整除,就说明整个数组就是这个周期的循环。**
|
||||
|
||||
|
@ -163,7 +163,7 @@ public:
|
||||
## 其他语言版本
|
||||
|
||||
|
||||
Java:
|
||||
### Java
|
||||
```Java
|
||||
class Solution {
|
||||
public int findMaxForm(String[] strs, int m, int n) {
|
||||
@ -192,7 +192,7 @@ class Solution {
|
||||
}
|
||||
```
|
||||
|
||||
Python:
|
||||
### Python
|
||||
```python
|
||||
class Solution:
|
||||
def findMaxForm(self, strs: List[str], m: int, n: int) -> int:
|
||||
@ -208,7 +208,7 @@ class Solution:
|
||||
return dp[m][n]
|
||||
```
|
||||
|
||||
Go:
|
||||
### Go
|
||||
```go
|
||||
func findMaxForm(strs []string, m int, n int) int {
|
||||
// 定义数组
|
||||
@ -294,7 +294,7 @@ func getMax(a,b int)int{
|
||||
}
|
||||
```
|
||||
|
||||
Javascript:
|
||||
### Javascript
|
||||
```javascript
|
||||
const findMaxForm = (strs, m, n) => {
|
||||
const dp = Array.from(Array(m+1), () => Array(n+1).fill(0));
|
||||
@ -323,7 +323,7 @@ const findMaxForm = (strs, m, n) => {
|
||||
};
|
||||
```
|
||||
|
||||
TypeScript:
|
||||
### TypeScript
|
||||
|
||||
> 滚动数组,二维数组法
|
||||
|
||||
@ -446,7 +446,80 @@ function isValidSubSet(strs: string[], m: number, n: number): boolean {
|
||||
}
|
||||
```
|
||||
|
||||
### Scala
|
||||
|
||||
背包:
|
||||
```scala
|
||||
object Solution {
|
||||
def findMaxForm(strs: Array[String], m: Int, n: Int): Int = {
|
||||
var dp = Array.ofDim[Int](m + 1, n + 1)
|
||||
|
||||
var (oneNum, zeroNum) = (0, 0)
|
||||
|
||||
for (str <- strs) {
|
||||
oneNum = 0
|
||||
zeroNum = 0
|
||||
for (i <- str.indices) {
|
||||
if (str(i) == '0') zeroNum += 1
|
||||
else oneNum += 1
|
||||
}
|
||||
|
||||
for (i <- m to zeroNum by -1) {
|
||||
for (j <- n to oneNum by -1) {
|
||||
dp(i)(j) = math.max(dp(i)(j), dp(i - zeroNum)(j - oneNum) + 1)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dp(m)(n)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
回溯法(超时):
|
||||
```scala
|
||||
object Solution {
|
||||
import scala.collection.mutable
|
||||
|
||||
var res = Int.MinValue
|
||||
|
||||
def test(str: String): (Int, Int) = {
|
||||
var (zero, one) = (0, 0)
|
||||
for (i <- str.indices) {
|
||||
if (str(i) == '1') one += 1
|
||||
else zero += 1
|
||||
}
|
||||
(zero, one)
|
||||
}
|
||||
|
||||
def travsel(strs: Array[String], path: mutable.ArrayBuffer[String], m: Int, n: Int, startIndex: Int): Unit = {
|
||||
if (startIndex > strs.length) {
|
||||
return
|
||||
}
|
||||
|
||||
res = math.max(res, path.length)
|
||||
|
||||
for (i <- startIndex until strs.length) {
|
||||
|
||||
var (zero, one) = test(strs(i))
|
||||
|
||||
// 如果0的个数小于m,1的个数小于n,则可以回溯
|
||||
if (zero <= m && one <= n) {
|
||||
path.append(strs(i))
|
||||
travsel(strs, path, m - zero, n - one, i + 1)
|
||||
path.remove(path.length - 1)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
def findMaxForm(strs: Array[String], m: Int, n: Int): Int = {
|
||||
res = Int.MinValue
|
||||
var path = mutable.ArrayBuffer[String]()
|
||||
travsel(strs, path, m, n, 0)
|
||||
res
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
-----------------------
|
||||
<div align="center"><img src=https://code-thinking.cdn.bcebos.com/pics/01二维码一.jpg width=500> </img></div>
|
||||
|
@ -156,9 +156,9 @@ dp[j] 表示:填满j(包括j)这么大容积的包,有dp[j]种方法
|
||||
|
||||
有哪些来源可以推出dp[j]呢?
|
||||
|
||||
不考虑nums[i]的情况下,填满容量为j - nums[i]的背包,有dp[j - nums[i]]种方法。
|
||||
不考虑nums[i]的情况下,填满容量为j的背包,有dp[j]种方法。
|
||||
|
||||
那么只要搞到nums[i]的话,凑成dp[j]就有dp[j - nums[i]] 种方法。
|
||||
那么考虑nums[i]的话(只要搞到nums[i]),凑成dp[j]就有dp[j - nums[i]] 种方法。
|
||||
|
||||
例如:dp[j],j 为5,
|
||||
|
||||
@ -251,7 +251,7 @@ dp[j] += dp[j - nums[i]];
|
||||
## 其他语言版本
|
||||
|
||||
|
||||
Java:
|
||||
### Java
|
||||
```java
|
||||
class Solution {
|
||||
public int findTargetSumWays(int[] nums, int target) {
|
||||
@ -272,7 +272,7 @@ class Solution {
|
||||
}
|
||||
```
|
||||
|
||||
Python:
|
||||
### Python
|
||||
```python
|
||||
class Solution:
|
||||
def findTargetSumWays(self, nums: List[int], target: int) -> int:
|
||||
@ -288,7 +288,7 @@ class Solution:
|
||||
return dp[bagSize]
|
||||
```
|
||||
|
||||
Go:
|
||||
### Go
|
||||
```go
|
||||
func findTargetSumWays(nums []int, target int) int {
|
||||
sum := 0
|
||||
@ -323,7 +323,7 @@ func abs(x int) int {
|
||||
}
|
||||
```
|
||||
|
||||
Javascript:
|
||||
### Javascript
|
||||
```javascript
|
||||
const findTargetSumWays = (nums, target) => {
|
||||
|
||||
@ -353,6 +353,8 @@ const findTargetSumWays = (nums, target) => {
|
||||
```
|
||||
|
||||
|
||||
### TypeScript
|
||||
|
||||
TypeScript:
|
||||
|
||||
```ts
|
||||
@ -375,7 +377,25 @@ function findTargetSumWays(nums: number[], target: number): number {
|
||||
};
|
||||
```
|
||||
|
||||
### Scala
|
||||
|
||||
```scala
|
||||
object Solution {
|
||||
def findTargetSumWays(nums: Array[Int], target: Int): Int = {
|
||||
var sum = nums.sum
|
||||
if (math.abs(target) > sum) return 0 // 此时没有方案
|
||||
if ((sum + target) % 2 == 1) return 0 // 此时没有方案
|
||||
var bagSize = (sum + target) / 2
|
||||
var dp = new Array[Int](bagSize + 1)
|
||||
dp(0) = 1
|
||||
for (i <- 0 until nums.length; j <- bagSize to nums(i) by -1) {
|
||||
dp(j) += dp(j - nums(i))
|
||||
}
|
||||
|
||||
dp(bagSize)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
-----------------------
|
||||
<div align="center"><img src=https://code-thinking.cdn.bcebos.com/pics/01二维码一.jpg width=500> </img></div>
|
||||
|
@ -263,7 +263,7 @@ var fib = function(n) {
|
||||
};
|
||||
```
|
||||
|
||||
TypeScript
|
||||
### TypeScript
|
||||
|
||||
```typescript
|
||||
function fib(n: number): number {
|
||||
@ -342,5 +342,33 @@ pub fn fib(n: i32) -> i32 {
|
||||
return fib(n - 1) + fib(n - 2);
|
||||
}
|
||||
```
|
||||
|
||||
### Scala
|
||||
|
||||
动态规划:
|
||||
```scala
|
||||
object Solution {
|
||||
def fib(n: Int): Int = {
|
||||
if (n <= 1) return n
|
||||
var dp = new Array[Int](n + 1)
|
||||
dp(1) = 1
|
||||
for (i <- 2 to n) {
|
||||
dp(i) = dp(i - 1) + dp(i - 2)
|
||||
}
|
||||
dp(n)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
递归:
|
||||
```scala
|
||||
object Solution {
|
||||
def fib(n: Int): Int = {
|
||||
if (n <= 1) return n
|
||||
fib(n - 1) + fib(n - 2)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
-----------------------
|
||||
<div align="center"><img src=https://code-thinking.cdn.bcebos.com/pics/01二维码一.jpg width=500> </img></div>
|
||||
|
@ -289,7 +289,22 @@ function change(amount: number, coins: number[]): number {
|
||||
};
|
||||
```
|
||||
|
||||
Scala:
|
||||
|
||||
```scala
|
||||
object Solution {
|
||||
def change(amount: Int, coins: Array[Int]): Int = {
|
||||
var dp = new Array[Int](amount + 1)
|
||||
dp(0) = 1
|
||||
for (i <- 0 until coins.length) {
|
||||
for (j <- coins(i) to amount) {
|
||||
dp(j) += dp(j - coins(i))
|
||||
}
|
||||
}
|
||||
dp(amount)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
-----------------------
|
||||
<div align="center"><img src=https://code-thinking.cdn.bcebos.com/pics/01二维码一.jpg width=500> </img></div>
|
||||
|
@ -65,6 +65,9 @@ public:
|
||||
};
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
那么我们也可以实现自己的reverse函数,其实和题目[344. 反转字符串](https://programmercarl.com/0344.反转字符串.html)道理是一样的。
|
||||
|
||||
下面我实现的reverse函数区间是左闭右闭区间,代码如下:
|
||||
@ -94,7 +97,24 @@ public:
|
||||
```
|
||||
|
||||
|
||||
另一种思路的解法
|
||||
|
||||
```CPP
|
||||
class Solution {
|
||||
public:
|
||||
string reverseStr(string s, int k) {
|
||||
int n = s.size(),pos = 0;
|
||||
while(pos < n){
|
||||
//剩余字符串大于等于k的情况
|
||||
if(pos + k < n) reverse(s.begin() + pos, s.begin() + pos + k);
|
||||
//剩余字符串不足k的情况
|
||||
else reverse(s.begin() + pos,s.end());
|
||||
pos += 2 * k;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
@ -205,7 +205,7 @@ func min(a, b int) int {
|
||||
Javascript:
|
||||
```javascript
|
||||
const minDistance = (word1, word2) => {
|
||||
let dp = Array.from(Array(word1.length + 1), () => Array(word2.length+1).fill(0));
|
||||
let dp = Array.from(new Array(word1.length + 1), () => Array(word2.length+1).fill(0));
|
||||
|
||||
for(let i = 1; i <= word1.length; i++) {
|
||||
dp[i][0] = i;
|
||||
|
@ -244,6 +244,44 @@ var predictPartyVictory = function(senateStr) {
|
||||
};
|
||||
```
|
||||
|
||||
## TypeScript
|
||||
|
||||
```typescript
|
||||
function predictPartyVictory(senate: string): string {
|
||||
// 数量差:Count(Radiant) - Count(Dire)
|
||||
let deltaRDCnt: number = 0;
|
||||
let hasR: boolean = true,
|
||||
hasD: boolean = true;
|
||||
const senateArr: string[] = senate.split('');
|
||||
while (hasR && hasD) {
|
||||
hasR = false;
|
||||
hasD = false;
|
||||
for (let i = 0, length = senateArr.length; i < length; i++) {
|
||||
if (senateArr[i] === 'R') {
|
||||
if (deltaRDCnt < 0) {
|
||||
senateArr[i] = '';
|
||||
} else {
|
||||
hasR = true;
|
||||
}
|
||||
deltaRDCnt++;
|
||||
} else if (senateArr[i] === 'D') {
|
||||
if (deltaRDCnt > 0) {
|
||||
senateArr[i] = '';
|
||||
} else {
|
||||
hasD = true;
|
||||
}
|
||||
deltaRDCnt--;
|
||||
}
|
||||
}
|
||||
}
|
||||
return hasR ? 'Radiant' : 'Dire';
|
||||
};
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
-----------------------
|
||||
<div align="center"><img src=https://code-thinking.cdn.bcebos.com/pics/01二维码一.jpg width=500> </img></div>
|
||||
|
@ -300,7 +300,7 @@ Javascript:
|
||||
> 动态规划:
|
||||
```javascript
|
||||
const findLengthOfLCIS = (nums) => {
|
||||
let dp = Array(nums.length).fill(1);
|
||||
let dp = new Array(nums.length).fill(1);
|
||||
|
||||
|
||||
for(let i = 0; i < nums.length - 1; i++) {
|
||||
|
@ -153,7 +153,7 @@ public:
|
||||
|
||||
## 其他语言版本
|
||||
|
||||
Java:
|
||||
### Java
|
||||
```java
|
||||
// 贪心思路
|
||||
class Solution {
|
||||
@ -198,7 +198,7 @@ class Solution { // 动态规划
|
||||
|
||||
|
||||
|
||||
Python:
|
||||
### Python
|
||||
|
||||
```python
|
||||
class Solution: # 贪心思路
|
||||
@ -216,7 +216,7 @@ class Solution: # 贪心思路
|
||||
return result
|
||||
```
|
||||
|
||||
Go:
|
||||
### Go
|
||||
```golang
|
||||
func maxProfit(prices []int, fee int) int {
|
||||
var minBuy int = prices[0] //第一天买入
|
||||
@ -241,7 +241,7 @@ func maxProfit(prices []int, fee int) int {
|
||||
return res
|
||||
}
|
||||
```
|
||||
Javascript:
|
||||
### Javascript
|
||||
```Javascript
|
||||
// 贪心思路
|
||||
var maxProfit = function(prices, fee) {
|
||||
@ -293,7 +293,7 @@ var maxProfit = function(prices, fee) {
|
||||
};
|
||||
```
|
||||
|
||||
TypeScript:
|
||||
### TypeScript
|
||||
|
||||
> 贪心
|
||||
|
||||
@ -335,8 +335,28 @@ function maxProfit(prices: number[], fee: number): number {
|
||||
};
|
||||
```
|
||||
|
||||
### Scala
|
||||
|
||||
贪心思路:
|
||||
|
||||
```scala
|
||||
object Solution {
|
||||
def maxProfit(prices: Array[Int], fee: Int): Int = {
|
||||
var result = 0
|
||||
var minPrice = prices(0)
|
||||
for (i <- 1 until prices.length) {
|
||||
if (prices(i) < minPrice) {
|
||||
minPrice = prices(i) // 比当前最小值还小
|
||||
}
|
||||
if (prices(i) > minPrice + fee) {
|
||||
result += prices(i) - minPrice - fee
|
||||
minPrice = prices(i) - fee
|
||||
}
|
||||
}
|
||||
result
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
-----------------------
|
||||
<div align="center"><img src=https://code-thinking.cdn.bcebos.com/pics/01二维码一.jpg width=500> </img></div>
|
||||
|
@ -246,7 +246,37 @@ function monotoneIncreasingDigits(n: number): number {
|
||||
```
|
||||
|
||||
|
||||
### Scala
|
||||
|
||||
直接转换为了整数数组:
|
||||
```scala
|
||||
object Solution {
|
||||
import scala.collection.mutable
|
||||
def monotoneIncreasingDigits(n: Int): Int = {
|
||||
var digits = mutable.ArrayBuffer[Int]()
|
||||
// 提取每位数字
|
||||
var temp = n // 因为 参数n 是不可变量所以需要赋值给一个可变量
|
||||
while (temp != 0) {
|
||||
digits.append(temp % 10)
|
||||
temp = temp / 10
|
||||
}
|
||||
// 贪心
|
||||
var flag = -1
|
||||
for (i <- 0 until (digits.length - 1) if digits(i) < digits(i + 1)) {
|
||||
flag = i
|
||||
digits(i + 1) -= 1
|
||||
}
|
||||
for (i <- 0 to flag) digits(i) = 9
|
||||
|
||||
// 拼接
|
||||
var res = 0
|
||||
for (i <- 0 until digits.length) {
|
||||
res += digits(i) * math.pow(10, i).toInt
|
||||
}
|
||||
res
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
-----------------------
|
||||
<div align="center"><img src=https://code-thinking.cdn.bcebos.com/pics/01二维码一.jpg width=500> </img></div>
|
||||
|
@ -323,5 +323,35 @@ int minCostClimbingStairs(int* cost, int costSize){
|
||||
return dp[i-1] < dp[i-2] ? dp[i-1] : dp[i-2];
|
||||
}
|
||||
```
|
||||
|
||||
### Scala
|
||||
|
||||
```scala
|
||||
object Solution {
|
||||
def minCostClimbingStairs(cost: Array[Int]): Int = {
|
||||
var dp = new Array[Int](cost.length)
|
||||
dp(0) = cost(0)
|
||||
dp(1) = cost(1)
|
||||
for (i <- 2 until cost.length) {
|
||||
dp(i) = math.min(dp(i - 1), dp(i - 2)) + cost(i)
|
||||
}
|
||||
math.min(dp(cost.length - 1), dp(cost.length - 2))
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
第二种思路: dp[i] 表示爬到第i-1层所需的最小花费,状态转移方程为: dp[i] = min(dp[i-1]+cost[i-1],dp[i-2]+cost[i-2])
|
||||
```scala
|
||||
object Solution {
|
||||
def minCostClimbingStairs(cost: Array[Int]): Int = {
|
||||
var dp = new Array[Int](cost.length + 1)
|
||||
for (i <- 2 until cost.length + 1) {
|
||||
dp(i) = math.min(dp(i - 1) + cost(i - 1), dp(i - 2) + cost(i - 2))
|
||||
}
|
||||
dp(cost.length)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
-----------------------
|
||||
<div align="center"><img src=https://code-thinking.cdn.bcebos.com/pics/01二维码一.jpg width=500> </img></div>
|
||||
|
@ -317,7 +317,31 @@ function partitionLabels(s: string): number[] {
|
||||
};
|
||||
```
|
||||
|
||||
### Scala
|
||||
|
||||
```scala
|
||||
object Solution {
|
||||
import scala.collection.mutable
|
||||
def partitionLabels(s: String): List[Int] = {
|
||||
var hash = new Array[Int](26)
|
||||
for (i <- s.indices) {
|
||||
hash(s(i) - 'a') = i
|
||||
}
|
||||
|
||||
var res = mutable.ListBuffer[Int]()
|
||||
var (left, right) = (0, 0)
|
||||
for (i <- s.indices) {
|
||||
right = math.max(hash(s(i) - 'a'), right)
|
||||
if (i == right) {
|
||||
res.append(right - left + 1)
|
||||
left = i + 1
|
||||
}
|
||||
}
|
||||
|
||||
res.toList
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
-----------------------
|
||||
|
@ -328,6 +328,37 @@ function lemonadeChange(bills: number[]): boolean {
|
||||
```
|
||||
|
||||
|
||||
### Scala
|
||||
|
||||
```scala
|
||||
object Solution {
|
||||
def lemonadeChange(bills: Array[Int]): Boolean = {
|
||||
var fiveNum = 0
|
||||
var tenNum = 0
|
||||
|
||||
for (i <- bills) {
|
||||
if (i == 5) fiveNum += 1
|
||||
if (i == 10) {
|
||||
if (fiveNum <= 0) return false
|
||||
tenNum += 1
|
||||
fiveNum -= 1
|
||||
}
|
||||
if (i == 20) {
|
||||
if (fiveNum > 0 && tenNum > 0) {
|
||||
tenNum -= 1
|
||||
fiveNum -= 1
|
||||
} else if (fiveNum >= 3) {
|
||||
fiveNum -= 3
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
true
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
-----------------------
|
||||
<div align="center"><img src=https://code-thinking.cdn.bcebos.com/pics/01二维码一.jpg width=500> </img></div>
|
||||
|
@ -177,7 +177,24 @@ function validMountainArray(arr: number[]): boolean {
|
||||
};
|
||||
```
|
||||
|
||||
## C#
|
||||
|
||||
```csharp
|
||||
public class Solution {
|
||||
public bool ValidMountainArray(int[] arr) {
|
||||
if (arr.Length < 3) return false;
|
||||
|
||||
int left = 0;
|
||||
int right = arr.Length - 1;
|
||||
|
||||
while (left + 1< arr.Length && arr[left] < arr[left + 1]) left ++;
|
||||
while (right > 0 && arr[right] < arr[right - 1]) right --;
|
||||
if (left == right && left != 0 && right != arr.Length - 1) return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
-----------------------
|
||||
|
@ -544,5 +544,40 @@ int minCameraCover(struct TreeNode* root){
|
||||
}
|
||||
```
|
||||
|
||||
### Scala
|
||||
|
||||
```scala
|
||||
object Solution {
|
||||
def minCameraCover(root: TreeNode): Int = {
|
||||
var result = 0
|
||||
def traversal(cur: TreeNode): Int = {
|
||||
// 空节点,该节点有覆盖
|
||||
if (cur == null) return 2
|
||||
var left = traversal(cur.left)
|
||||
var right = traversal(cur.right)
|
||||
// 情况1,左右节点都有覆盖
|
||||
if (left == 2 && right == 2) {
|
||||
return 0
|
||||
}
|
||||
// 情况2
|
||||
if (left == 0 || right == 0) {
|
||||
result += 1
|
||||
return 1
|
||||
}
|
||||
// 情况3
|
||||
if (left == 1 || right == 1) {
|
||||
return 2
|
||||
}
|
||||
-1
|
||||
}
|
||||
|
||||
if (traversal(root) == 0) {
|
||||
result += 1
|
||||
}
|
||||
result
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
-----------------------
|
||||
<div align="center"><img src=https://code-thinking.cdn.bcebos.com/pics/01二维码一.jpg width=500> </img></div>
|
||||
|
@ -376,6 +376,25 @@ func removeDuplicates(_ s: String) -> String {
|
||||
```
|
||||
|
||||
|
||||
C#:
|
||||
```csharp
|
||||
public string RemoveDuplicates(string s) {
|
||||
//拿字符串直接作为栈,省去了栈还要转为字符串的操作
|
||||
StringBuilder res = new StringBuilder();
|
||||
|
||||
foreach(char c in s){
|
||||
if(res.Length > 0 && res[res.Length-1] == c){
|
||||
res.Remove(res.Length-1, 1);
|
||||
}else{
|
||||
res.Append(c);
|
||||
}
|
||||
}
|
||||
|
||||
return res.ToString();
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
PHP:
|
||||
```php
|
||||
class Solution {
|
||||
|
@ -3,7 +3,6 @@
|
||||
<img src="https://code-thinking-1253855093.file.myqcloud.com/pics/20210924105952.png" width="1000"/>
|
||||
</a>
|
||||
<p align="center"><strong><a href="https://mp.weixin.qq.com/s/tqCxrMEU-ajQumL1i8im9A">参与本项目</a>,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
# 动态规划:最后一块石头的重量 II
|
||||
|
||||
## 1049. 最后一块石头的重量 II
|
||||
|
||||
@ -152,7 +151,7 @@ public:
|
||||
## 其他语言版本
|
||||
|
||||
|
||||
Java:
|
||||
### Java:
|
||||
|
||||
一维数组版本
|
||||
```Java
|
||||
@ -212,7 +211,7 @@ class Solution {
|
||||
|
||||
```
|
||||
|
||||
Python:
|
||||
### Python:
|
||||
```python
|
||||
class Solution:
|
||||
def lastStoneWeightII(self, stones: List[int]) -> int:
|
||||
@ -225,7 +224,7 @@ class Solution:
|
||||
return sumweight - 2 * dp[target]
|
||||
```
|
||||
|
||||
Go:
|
||||
### Go:
|
||||
```go
|
||||
func lastStoneWeightII(stones []int) int {
|
||||
// 15001 = 30 * 1000 /2 +1
|
||||
@ -254,7 +253,7 @@ func max(a, b int) int {
|
||||
}
|
||||
```
|
||||
|
||||
JavaScript版本
|
||||
### JavaScript
|
||||
|
||||
```javascript
|
||||
/**
|
||||
@ -277,7 +276,7 @@ var lastStoneWeightII = function (stones) {
|
||||
};
|
||||
```
|
||||
|
||||
C版本
|
||||
### C
|
||||
```c
|
||||
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
|
||||
|
||||
@ -308,8 +307,7 @@ int lastStoneWeightII(int* stones, int stonesSize){
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
TypeScript版本
|
||||
### TypeScript:
|
||||
|
||||
```ts
|
||||
function lastStoneWeightII(stones: number[]): number {
|
||||
@ -327,7 +325,47 @@ function lastStoneWeightII(stones: number[]): number {
|
||||
};
|
||||
```
|
||||
|
||||
### Scala
|
||||
|
||||
滚动数组:
|
||||
```scala
|
||||
object Solution {
|
||||
def lastStoneWeightII(stones: Array[Int]): Int = {
|
||||
var sum = stones.sum
|
||||
var half = sum / 2
|
||||
var dp = new Array[Int](half + 1)
|
||||
|
||||
// 遍历
|
||||
for (i <- 0 until stones.length; j <- half to stones(i) by -1) {
|
||||
dp(j) = math.max(dp(j), dp(j - stones(i)) + stones(i))
|
||||
}
|
||||
|
||||
sum - 2 * dp(half)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
二维数组:
|
||||
```scala
|
||||
object Solution {
|
||||
def lastStoneWeightII(stones: Array[Int]): Int = {
|
||||
var sum = stones.sum
|
||||
var half = sum / 2
|
||||
var dp = Array.ofDim[Int](stones.length, half + 1)
|
||||
|
||||
// 初始化
|
||||
for (j <- stones(0) to half) dp(0)(j) = stones(0)
|
||||
|
||||
// 遍历
|
||||
for (i <- 1 until stones.length; j <- 1 to half) {
|
||||
if (j - stones(i) >= 0) dp(i)(j) = stones(i) + dp(i - 1)(j - stones(i))
|
||||
dp(i)(j) = math.max(dp(i)(j), dp(i - 1)(j))
|
||||
}
|
||||
|
||||
sum - 2 * dp(stones.length - 1)(half)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
@ -108,11 +108,38 @@ class Solution {
|
||||
### Python
|
||||
|
||||
```python
|
||||
class Solution:
|
||||
def balancedStringSplit(self, s: str) -> int:
|
||||
diff = 0 #右左差值
|
||||
ans = 0
|
||||
for c in s:
|
||||
if c == "L":
|
||||
diff -= 1
|
||||
else:
|
||||
diff += 1
|
||||
if tilt == 0:
|
||||
ans += 1
|
||||
return ans
|
||||
```
|
||||
|
||||
### Go
|
||||
|
||||
```go
|
||||
func balancedStringSplit(s string) int {
|
||||
diff := 0 // 右左差值
|
||||
ans := 0
|
||||
for _, c := range s {
|
||||
if c == 'L' {
|
||||
diff--
|
||||
}else {
|
||||
diff++
|
||||
}
|
||||
if diff == 0 {
|
||||
ans++
|
||||
}
|
||||
}
|
||||
return ans
|
||||
}
|
||||
```
|
||||
|
||||
### JavaScript
|
||||
|
@ -418,7 +418,7 @@ function combinationSum2(candidates, target) {
|
||||
|
||||
**47. 全排列 II**
|
||||
|
||||
```javaescript
|
||||
```javascript
|
||||
function permuteUnique(nums) {
|
||||
const resArr = [];
|
||||
const usedArr = [];
|
||||
|
@ -502,7 +502,41 @@ const size = 4;
|
||||
console.log(testWeightBagProblem(weight, value, size));
|
||||
```
|
||||
|
||||
### Scala
|
||||
|
||||
```scala
|
||||
object Solution {
|
||||
// 01背包
|
||||
def test_2_wei_bag_problem1(): Unit = {
|
||||
var weight = Array[Int](1, 3, 4)
|
||||
var value = Array[Int](15, 20, 30)
|
||||
var baseweight = 4
|
||||
|
||||
// 二维数组
|
||||
var dp = Array.ofDim[Int](weight.length, baseweight + 1)
|
||||
|
||||
// 初始化
|
||||
for (j <- weight(0) to baseweight) {
|
||||
dp(0)(j) = value(0)
|
||||
}
|
||||
|
||||
// 遍历
|
||||
for (i <- 1 until weight.length; j <- 1 to baseweight) {
|
||||
if (j - weight(i) >= 0) dp(i)(j) = dp(i - 1)(j - weight(i)) + value(i)
|
||||
dp(i)(j) = math.max(dp(i)(j), dp(i - 1)(j))
|
||||
}
|
||||
|
||||
// 打印数组
|
||||
dp.foreach(x => println("[" + x.mkString(",") + "]"))
|
||||
|
||||
dp(weight.length - 1)(baseweight) // 最终返回
|
||||
}
|
||||
|
||||
def main(args: Array[String]): Unit = {
|
||||
test_2_wei_bag_problem1()
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
-----------------------
|
||||
<div align="center"><img src=https://code-thinking.cdn.bcebos.com/pics/01二维码一.jpg width=500> </img></div>
|
||||
|
@ -375,7 +375,33 @@ console.log(testWeightBagProblem(weight, value, size));
|
||||
|
||||
```
|
||||
|
||||
### Scala
|
||||
|
||||
```scala
|
||||
object Solution {
|
||||
// 滚动数组
|
||||
def test_1_wei_bag_problem(): Unit = {
|
||||
var weight = Array[Int](1, 3, 4)
|
||||
var value = Array[Int](15, 20, 30)
|
||||
var baseweight = 4
|
||||
|
||||
// dp数组
|
||||
var dp = new Array[Int](baseweight + 1)
|
||||
|
||||
// 遍历
|
||||
for (i <- 0 until weight.length; j <- baseweight to weight(i) by -1) {
|
||||
dp(j) = math.max(dp(j), dp(j - weight(i)) + value(i))
|
||||
}
|
||||
|
||||
// 打印数组
|
||||
println("[" + dp.mkString(",") + "]")
|
||||
}
|
||||
|
||||
def main(args: Array[String]): Unit = {
|
||||
test_1_wei_bag_problem()
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
-----------------------
|
||||
<div align="center"><img src=https://code-thinking.cdn.bcebos.com/pics/01二维码一.jpg width=500> </img></div>
|
||||
|
@ -359,7 +359,27 @@ function test_CompletePack(): void {
|
||||
test_CompletePack();
|
||||
```
|
||||
|
||||
Scala:
|
||||
|
||||
```scala
|
||||
// 先遍历物品,再遍历背包容量
|
||||
object Solution {
|
||||
def test_CompletePack() {
|
||||
var weight = Array[Int](1, 3, 4)
|
||||
var value = Array[Int](15, 20, 30)
|
||||
var baseweight = 4
|
||||
|
||||
var dp = new Array[Int](baseweight + 1)
|
||||
|
||||
for (i <- 0 until weight.length) {
|
||||
for (j <- weight(i) to baseweight) {
|
||||
dp(j) = math.max(dp(j), dp(j - weight(i)) + value(i))
|
||||
}
|
||||
}
|
||||
dp(baseweight)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
-----------------------
|
||||
|
Reference in New Issue
Block a user