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 all commits
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
54 changes: 54 additions & 0 deletions Week_04/id_117/LeetCode_169_117.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package solution

/*
169. Majority Element

Given an array of size n, find the majority element. The majority element is the element that appears more than ⌊ n/2 ⌋ times.

You may assume that the array is non-empty and the majority element always exist in the array.

Example 1:

Input: [3,2,3]
Output: 3
Example 2:

Input: [2,2,1,1,1,2,2]
Output: 2
*/

// 方法一, 直接定义map[int]int来存放数据, 找出出现次数最多的数即可, map的长度为 n/2 + 1, 空间复杂度O(n), 时间复杂度O(n)
func majorityElement(nums []int) int {
mps := make(map[int]int, 0)
numsLen := len(nums)
res := 0
for _, item := range nums {
mps[item]++
if mps[item] > numsLen/2 {
res = item
}
}
return res
}

// 方法二, 分治法思想
// 摩尔投票法,先假设第一个数过半,并设置count=1,之后遍历剩余数据,如果相同则+1,如果不同则-1; 前提条件是存在元素的个数大于n/2
func majorityElement2(nums []int) int {
numsLen := len(nums)
if numsLen == 0 {
return 0
}
majar := nums[0]
count := 1
for i := 1; i < numsLen; i++ {
if count == 0 {
majar = nums[i]
}
if majar == nums[i] {
count++
} else {
count--
}
}
return majar
}
32 changes: 32 additions & 0 deletions Week_04/id_117/LeetCode_169_117_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package solution

import (
"testing"
)

func Test_eventualSafeNodes(t *testing.T) {
testData := []map[string]interface{}{
map[string]interface{}{
"name": "test1",
"ins": []int{3, 2, 3},
"outs": 3,
},
map[string]interface{}{
"name": "test1",
"ins": []int{2, 2, 1, 1, 1, 2, 2},
"outs": 2,
},
}
for _, tt := range testData {
name := tt["name"].(string)
ins := tt["ins"].([]int)
outs := tt["outs"].(int)
t.Run(name, func(t *testing.T) {
got := majorityElement2(ins)
eq := got == outs
if !eq {
t.Errorf("eventualSafeNodes() = %v, want %v", got, outs)
}
})
}
}
131 changes: 131 additions & 0 deletions Week_04/id_117/LeetCode_211_117.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
package solution

/*
211. Add and Search Word - Data structure design

Design a data structure that supports the following two operations:

void addWord(word)
bool search(word)
search(word) can search a literal word or a regular expression string containing only letters a-z or .. A . means it can represent any one letter.

Example:

addWord("bad")
addWord("dad")
addWord("mad")
search("pad") -> false
search("bad") -> true
search(".ad") -> true
search("b..") -> true
Note:
You may assume that all words are consist of lowercase letters a-z.
*/

/**
* 测试案例
* Your WordDictionary object will be instantiated and called as such:
* obj := Constructor();
* obj.AddWord(word);
* param_2 := obj.Search(word);
*/

// 方法一
type WordDictionary struct {
Words map[int][]string
}

/** Initialize your data structure here. */
func Constructor() WordDictionary {
return WordDictionary{Words: make(map[int][]string)}
}

/** Adds a word into the data structure. */
func (this *WordDictionary) AddWord(word string) {
m := len(word)
if len(this.Words[m]) > 0 {
this.Words[m] = append(this.Words[m], word)
} else {
this.Words[m] = []string{word}
}
}

/** Returns if the word is in the data structure. A word could contain the dot character '.' to represent any one letter. */
func (this *WordDictionary) Search(word string) bool {
m := len(word)
if this.Words[m] == nil {
return false
}
// 当前列表中元素
w := len(this.Words[m])
for i := 0; i < w; i++ {
tmp := true
for j := 0; j < m; j++ {
if word[j] != '.' && word[j] != this.Words[m][i][j] {
tmp = false
continue
}
}
if tmp {
return true
}
}

return false
}

// 方法二
type WordDictionary2 struct {
children map[rune]*WordDictionary2
isWord bool
}

/** Initialize your data structure here. */
func Constructor2() WordDictionary2 {
return WordDictionary2{children: make(map[rune]*WordDictionary2)}
}

/** Adds a word into the data structure. */
func (this *WordDictionary2) AddWord2(word string) {
parent := this
for _, v := range word {
// 判断是否已存储在树中
if child, ok := parent.children[v]; !ok {
newDic := &WordDictionary2{
children: make(map[rune]*WordDictionary2),
isWord: false,
}
parent.children[v] = newDic
parent = newDic
} else {
parent = child
}
}
parent.isWord = true
}

/** Returns if the word is in the data structure. A word could contain the dot character '.' to represent any one letter. */
func (this *WordDictionary2) Search2(word string) bool {
parent := this
wLen := len(word)
for i := 0; i < wLen; i++ {
if word[i] == '.' {
// 递归查找
mapStatus := false
for _, v := range parent.children {
if v.Search2(word[i+1:]) {
mapStatus = true
}
}
return mapStatus
} else {
// 非.字符直接判读
if _, ok := parent.children[rune(word[i])]; !ok {
return false
}
}
// 移动指针
parent = parent.children[rune(word[i])]
}
return len(parent.children) == 0 || parent.isWord
}
36 changes: 36 additions & 0 deletions Week_04/id_117/LeetCode_211_117_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package solution

import (
"testing"
)

func Test_Search(t *testing.T) {
testData := []map[string]interface{}{
map[string]interface{}{
"name": "test1",
"ins": []string{"bad", "dad", "mad"},
"finds": []string{"pad", "bad", ".ad", "b.."},
"outs": []bool{false, true, true, true},
},
}

for _, tt := range testData {
name := tt["name"].(string)
finds := tt["finds"].([]string)
ins := tt["ins"].([]string)
outs := tt["outs"].([]bool)
t.Run(name, func(t *testing.T) {
obj := Constructor2()
for _, word := range ins {
obj.AddWord2(word)
}
for k, word := range finds {

got := obj.Search2(word)
if got != outs[k] {
t.Errorf("Search got= %v, want %v, k=%d", got, outs[k], k)
}
}
})
}
}
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) // [2, 33]结果
parts2Res := diffWaysToCompute(parts2) // [2, 1]结果
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.是否可以使用动态规划来实现,在某一个数字的组合种类为前面组合种类递推
*/
Loading