This commit is contained in:
programmercarl
2022-08-03 15:56:24 +08:00
52 changed files with 1373 additions and 89 deletions

View File

@ -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

View File

@ -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

View File

@ -142,7 +142,7 @@ public:
```
* 时间复杂度O(log n)
* 间复杂度O(1)
* 间复杂度O(1)
效率如下:
![35_搜索插入位置2](https://img-blog.csdnimg.cn/2020121623272877.png)

View File

@ -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

View File

@ -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

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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

View File

@ -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>

View File

@ -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;

View File

@ -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..j1])时为回文串
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

View File

@ -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 // 求和
}
}
```
-----------------------

View File

@ -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

View File

@ -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

View File

@ -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>

View File

@ -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

View File

@ -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>

View File

@ -127,8 +127,6 @@ class Solution:
if record[i] != 0:
#record数组如果有的元素不为零0说明字符串s和t 一定是谁多了字符或者谁少了字符。
return False
#如果有一个元素不为零则可以判断字符串s和t不是字母异位词
break
return True
```

View File

@ -44,6 +44,8 @@ dp[i][j]第i天状态为j所剩的最多现金为dp[i][j]。
* 状态三:今天卖出了股票
* 状态四:今天为冷冻期状态,但冷冻期状态不可持续,只有一天!
![](https://img-blog.csdnimg.cn/518d5baaf33f4b2698064f8efb42edbf.png)
j的状态为
* 0状态一
@ -57,7 +59,7 @@ j的状态为
**注意这里的每一个状态,例如状态一,是买入股票状态并不是说今天已经就买入股票,而是说保存买入股票的状态即:可能是前几天买入的,之后一直没操作,所以保持买入股票的状态**
2. 确定递推公式
1. 确定递推公式
达到买入股票状态状态一dp[i][0],有两个具体操作:

View File

@ -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>

View File

@ -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)
}
}
```
-----------------------

View File

@ -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
}
}
```
-----------------------

View File

@ -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>

View File

@ -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
}
}
```

View File

@ -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
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
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) #右递归
return root
```

View File

@ -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>

View File

@ -134,7 +134,7 @@ next 数组记录的就是最长相同前后缀 [字符串KMP算法精讲](ht
数组长度为len。
如果len % (len - (next[len - 1] + 1)) == 0 ,则说明 (数组长度-最长相等前后缀的长度) 正好可以被 数组的长度整除,说明该字符串有重复的子字符串。
如果len % (len - (next[len - 1] + 1)) == 0 ,则说明数组的长度正好可以被 (数组长度-最长相等前后缀的长度) 整除 ,说明该字符串有重复的子字符串。
**数组长度减去最长相同前后缀的长度相当于是第一个周期的长度,也就是一个周期的长度,如果这个周期可以被整除,就说明整个数组就是这个周期的循环。**

View File

@ -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的个数小于m1的个数小于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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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;
}
};
```

View File

@ -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;

View File

@ -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>

View File

@ -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++) {

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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
}
}
```
-----------------------

View File

@ -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>

View File

@ -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;
}
}
```
-----------------------

View File

@ -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>

View File

@ -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 {

View File

@ -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)
}
}
```

View File

@ -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

View File

@ -418,7 +418,7 @@ function combinationSum2(candidates, target) {
**47. 全排列 II**
```javaescript
```javascript
function permuteUnique(nums) {
const resArr = [];
const usedArr = [];

View File

@ -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>

View File

@ -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>

View File

@ -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)
}
}
```
-----------------------