Skip to content

commit 4rd homework #916

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Add 241
  • Loading branch information
hapiman committed May 10, 2019
commit 3caca3eb6e2150abb7f952d00693492d08c04a35
103 changes: 103 additions & 0 deletions Week_04/id_117/LeetCode_241_117.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
package solution

import (
"fmt"
"strconv"
)

/*
241. Different Ways to Add Parentheses

Given a string of numbers and operators, return all possible results from computing all the different possible ways to group numbers and operators. The valid operators are +, - and *.

Example 1:

Input: "2-1-1"
Output: [0, 2]
Explanation:
((2-1)-1) = 0
(2-(1-1)) = 2
Example 2:

Input: "2*3-4*5"
Output: [-34, -14, -10, -10, 10]
Explanation:
(2*(3-(4*5))) = -34
((2*3)-(4*5)) = -14
((2*(3-4))*5) = -10
(2*((3-4)*5)) = -10
(((2*3)-4)*5) = 10
*/

/*
方法1,直接for遍历,然后根据运算符来执行判断, 为了减少计算次数,最好使用map来保存已经计算的值
*/

func diffWaysToCompute(input string) []int {
ans := make([]int, 0)
for i := 0; i < len(input); i++ {
if input[i] == '-' || input[i] == '+' || input[i] == '*' {
parts1 := input[0:i]
parts2 := input[i+1:]
parts1Res := diffWaysToCompute(parts1)
parts2Res := diffWaysToCompute(parts2)
for _, m := range parts1Res {
for _, n := range parts2Res {
c := 0
if input[i] == '*' {
c = m * n
}
if input[i] == '+' {
c = m + n
}
if input[i] == '-' {
c = m - n
}
ans = append(ans, c)
}
}
}
}

if len(ans) == 0 {
x, _ := strconv.Atoi(input)
ans = append(ans, x)
}

return ans
}

/*
分析:
1.有多少个运算符就有多少个括号
2.从第一个数开始递归查找,每一个运算符都有两种方式
3.表达式如何存储?
*/
func diffWaysToCompute2(input string) []int {
exps := make([]string, 0) // 表达式
ans := make([]int, 0) // 表达式计算值
curStr := input
compute(input, &exps, curStr)
return ans
}

func compute(input string, exps *[]string, curStr string) {
// 主逻辑, 每次去掉一个数字和运算符
symbolNum := len(input) / 2
if symbolNum == 1 {
return
}
fmt.Println("curStr ====>", curStr)
// 左边第一个数加i+1个括号
for i := 0; i < symbolNum; i++ {
curStr = fmt.Sprintf("(%s)", curStr)
fmt.Println("curStr ===>", curStr)
compute(input[2:], exps, curStr)
}
}

/*
设想:
1.是否可以将操作符和数字分别取出来,然后计算
2.是否可以使用动态规划来实现,在某一个数字的组合种类为前面组合种类递推
*/
40 changes: 40 additions & 0 deletions Week_04/id_117/LeetCode_241_117_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package solution

import (
"reflect"
"sort"
"testing"
)

func Test_diffWaysToCompute(t *testing.T) {
testData := []map[string]interface{}{
map[string]interface{}{
"name": "test1",
"ins": "2-1-1",
"outs": []int{0, 2},
},
map[string]interface{}{
"name": "test1",
"ins": "2*3-4*5",
"outs": []int{-34, -14, -10, -10, 10},
},
map[string]interface{}{
"name": "test1",
"ins": "2-1",
"outs": []int{1},
},
}
for _, tt := range testData {
name := tt["name"].(string)
ins := tt["ins"].(string)
outs := tt["outs"].([]int)
t.Run(name, func(t *testing.T) {
got := diffWaysToCompute(ins)
sort.Ints(got)
eq := reflect.DeepEqual(got, outs)
if !eq {
t.Errorf("eventualSafeNodes() = %v, want %v", got, outs)
}
})
}
}
7 changes: 7 additions & 0 deletions Week_04/id_117/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,10 @@
方法一, 直接定义map[int]int来存放数据, 找出出现次数最多的数即可, map的长度为 n/2 + 1, 空间复杂度O(n), 时间复杂度O(n)

方法二, 分治法思想, 摩尔投票法,先假设第一个数过半,并设置count=1,之后遍历剩余数据,如果相同则+1,如果不同则-1; 前提条件是存在元素的个数大于n/2

### 241
方法一,直接for遍历,然后根据运算符来执行判断, 这里的收获是在每一层定义ans来保存当前的原始值或者计算值

方法二,使用动态规划,定义dp为三维数组dp[][][]int

方法三,希望能够将每一个表达式计算出来,但是不知如何保存