Skip to content

Commit

Permalink
Merge branch 'master' of https://github.com/cxjwin/go-algocasts
Browse files Browse the repository at this point in the history
  • Loading branch information
smart committed May 22, 2019
2 parents 826f098 + 9b94960 commit 3572bce
Show file tree
Hide file tree
Showing 12 changed files with 451 additions and 58 deletions.
43 changes: 43 additions & 0 deletions leetcode/leetcode153/find_minimum_in_rotated_sorted_array.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package leetcode153

func findMin(nums []int) int {
if nums == nil || len(nums) == 0 {
return 0
}

low, high := 0, len(nums)-1

for low < high {
mid := low + (high-low)/2
if nums[mid] > nums[high] {
low = mid + 1
} else {
high = mid
}
}

return nums[low]
}

func findMinEarlyReturn(nums []int) int {
if nums == nil || len(nums) == 0 {
return 0
}

low, high := 0, len(nums)-1

for low < high {
if nums[low] < nums[high] {
return nums[low]
}

mid := low + (high-low)/2
if nums[mid] > nums[high] {
low = mid + 1
} else {
high = mid
}
}

return nums[low]
}
15 changes: 15 additions & 0 deletions leetcode/leetcode153/find_minimum_in_rotated_sorted_array_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package leetcode153

import "testing"

func TestFindMin(t *testing.T) {
type testFunc func([]int) int
testBody := func(f testFunc, t *testing.T) {
nums := []int{4, 5, 6, 7, 0, 1, 2}
if f(nums) != 0 {
t.Error("4, 5, 6, 7, 0, 1, 2 -> 0")
}
}
testBody(findMin, t)
testBody(findMinEarlyReturn, t)
}
56 changes: 28 additions & 28 deletions leetcode/leetcode207/course_schedule.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package leetcode207

// https://leetcode.com/problems/course-schedule/

func hasCycle(graph map[int][]int, checked []bool, visited []bool, v int) bool {
func hasCycle(graph [][]int, checked []bool, visited []bool, v int) bool {
if visited[v] {
return true
}
Expand All @@ -16,7 +16,6 @@ func hasCycle(graph map[int][]int, checked []bool, visited []bool, v int) bool {
}

checked[v] = true
visited[v] = false

return false
}
Expand All @@ -26,23 +25,22 @@ func canFinish(numCourses int, prerequisites [][]int) bool {
return true
}

m := make(map[int][]int)
graph := make([][]int, numCourses)
for i := 0; i < numCourses; i++ {
graph[i] = make([]int, 0)
}

for _, pair := range prerequisites {
arr, ok := m[pair[1]]
if !ok {
arr = []int{pair[0]}
} else {
arr = append(arr, pair[0])
}
m[pair[1]] = arr
for _, v := range prerequisites {
idx := v[1]
val := v[0]
graph[idx] = append(graph[idx], val)
}

checked := make([]bool, numCourses)
visited := make([]bool, numCourses)

for i := 0; i < numCourses; i++ {
if !checked[i] && hasCycle(m, checked, visited, i) {
visited := make([]bool, numCourses)
if !checked[i] && hasCycle(graph, checked, visited, i) {
return false
}
}
Expand All @@ -55,38 +53,40 @@ func canFinishTopoSort(numCourses int, prerequisites [][]int) bool {
return true
}

inDegree := make([]int, numCourses)

graph := make([][]int, numCourses)
for i := 0; i < numCourses; i++ {
graph[i] = make([]int, 0)
}

inDegrees := make([]int, numCourses)
for _, v := range prerequisites {
// set graph
arr := graph[v[1]]
arr = append(arr, v[0])
graph[v[1]] = arr
inDegree[v[0]]++
// set inDegrees
inDegrees[v[0]]++
}

queue := make([]int, 0)
for i, v := range inDegree {
st := make([]int, 0)
for i, v := range inDegrees {
if v == 0 {
queue = append(queue, i)
st = append(st, i)
}
}

count := 0

for len(queue) != 0 {
idx := queue[len(queue)-1]
queue = queue[:len(queue)-1]

for len(st) != 0 {
// pop
idx := st[len(st)-1]
st = st[:len(st)-1]
count++
for _, i := range graph[idx] {
inDegree[i]--
if inDegree[i] == 0 {
queue = append(queue, i)

arr := graph[idx]
for _, v := range arr {
inDegrees[v]--
if inDegrees[v] == 0 {
st = append(st, v)
}
}
}
Expand Down
15 changes: 15 additions & 0 deletions leetcode/leetcode207/course_schedule_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,21 @@ package leetcode207

import "testing"

func TestHasCycle(t *testing.T) {
input := [][]int{
{1},
{2},
{0},
}

checked := make([]bool, 3)
visited := make([]bool, 3)
res := hasCycle(input, checked, visited, 0)
if !res {
t.Error("has cycle")
}
}

func TestCanFinish(t *testing.T) {
type testFunc func(int, [][]int) bool

Expand Down
49 changes: 47 additions & 2 deletions leetcode/leetcode210/course_schedule_ii.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ func hasCycle(graph map[int][]int, checked []bool, visited []bool, order *[]int,

*order = append(*order, v)
checked[v] = true
visited[v] = false

return false
}
Expand All @@ -39,11 +38,11 @@ func findOrder(numCourses int, prerequisites [][]int) []int {
}

checked := make([]bool, numCourses)
visited := make([]bool, numCourses)
temp := make([]int, 0)
res := &temp

for i := 0; i < numCourses; i++ {
visited := make([]bool, numCourses)
if !checked[i] && hasCycle(m, checked, visited, res, i) {
return []int{}
}
Expand All @@ -57,3 +56,49 @@ func findOrder(numCourses int, prerequisites [][]int) []int {

return output
}

func findOrderTopoSort(numCourses int, prerequisites [][]int) []int {
if numCourses <= 1 || prerequisites == nil || len(prerequisites) == 0 {
return []int{}
}

graph := make([][]int, numCourses)
for i := 0; i < numCourses; i++ {
graph[i] = make([]int, 0)
}

inDegrees := make([]int, numCourses)
for _, v := range prerequisites {
arr := graph[v[1]]
arr = append(arr, v[0])
graph[v[1]] = arr

inDegrees[v[0]]++
}

st := make([]int, 0)
for _, v := range inDegrees {
if v == 0 {
st = append(st, v)
}
}

output := make([]int, 0)

for len(st) != 0 {
idx := st[len(st)-1]
st = st[:len(st)-1]

output = append(output, idx)

arr := graph[idx]
for _, v := range arr {
inDegrees[v]--
if inDegrees[v] == 0 {
st = append(st, v)
}
}
}

return output
}
63 changes: 35 additions & 28 deletions leetcode/leetcode210/course_schedule_ii_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,35 +6,42 @@ import (
)

func TestFindOrder(t *testing.T) {
case1 := [][]int{
{1, 0},
{3, 0},
{3, 1},
{2, 1},
{2, 3},
{4, 2},
{4, 3},
}
if !reflect.DeepEqual(findOrder(5, case1), []int{0, 1, 3, 2, 4}) {
t.Error("case1 => 0, 1, 3, 2, 4")
}
type testFunc func(int, [][]int) []int

case2 := [][]int{
{1, 0},
}
if !reflect.DeepEqual(findOrder(2, case2), []int{0, 1}) {
t.Error("case2 => 0, 1")
}
testBody := func(f testFunc, t *testing.T) {
case1 := [][]int{
{1, 0},
{3, 0},
{3, 1},
{2, 1},
{2, 3},
{4, 2},
{4, 3},
}
if !reflect.DeepEqual(f(5, case1), []int{0, 1, 3, 2, 4}) {
t.Error("case1 => 0, 1, 3, 2, 4")
}

case3 := [][]int{
{1, 0},
{2, 0},
{3, 1},
{3, 2},
}
res := findOrder(4, case3)
if !reflect.DeepEqual(res, []int{0, 1, 2, 3}) &&
!reflect.DeepEqual(res, []int{0, 2, 1, 3}) {
t.Error("case3 => 0, 1, 2, 3 or 0, 2, 1, 3")
case2 := [][]int{
{1, 0},
}
if !reflect.DeepEqual(f(2, case2), []int{0, 1}) {
t.Error("case2 => 0, 1")
}

case3 := [][]int{
{1, 0},
{2, 0},
{3, 1},
{3, 2},
}
res := f(4, case3)
if !reflect.DeepEqual(res, []int{0, 1, 2, 3}) &&
!reflect.DeepEqual(res, []int{0, 2, 1, 3}) {
t.Error("case3 => 0, 1, 2, 3 or 0, 2, 1, 3")
}
}

testBody(findOrder, t)
testBody(findOrderTopoSort, t)
}
48 changes: 48 additions & 0 deletions leetcode/leetcode54/spiral_matrix.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package leetcode54

func spiralOrder(matrix [][]int) []int {
if matrix == nil || len(matrix) == 0 || len(matrix[0]) == 0 {
return []int{}
}

top, left, bottom, right := 0, 0, len(matrix)-1, len(matrix[0])-1

res := make([]int, 0)

for {

for i := left; i <= right; i++ {
res = append(res, matrix[top][i])
}
top++
if top > bottom {
break
}

for i := top; i <= bottom; i++ {
res = append(res, matrix[i][right])
}
right--
if right < left {
break
}

for i := right; i >= left; i-- {
res = append(res, matrix[bottom][i])
}
bottom--
if bottom < top {
break
}

for i := bottom; i >= top; i-- {
res = append(res, matrix[i][left])
}
left++
if left > right {
break
}
}

return res
}
Loading

0 comments on commit 3572bce

Please sign in to comment.