From 08410d94b544905dfa3d279c3589d67b318a9ce0 Mon Sep 17 00:00:00 2001 From: Atin Bainada Date: Sun, 7 Mar 2021 22:19:25 +0530 Subject: [PATCH] Interval Scheduling, Quick Sort, Insertion Sort in Go (#102) * Interval Scheduling, Quick Sort, Insertion Sort in Go * Update quick-sort.go * Update interval-scheduling.go --- scheduling/README.md | 3 ++ scheduling/go/interval-scheduling.go | 47 ++++++++++++++++++++++++++++ sorting/README.md | 3 ++ sorting/go/insertion-sort.go | 34 ++++++++++++++++++++ sorting/go/quick-sort.go | 43 +++++++++++++++++++++++++ 5 files changed, 130 insertions(+) create mode 100644 scheduling/go/interval-scheduling.go create mode 100644 sorting/go/insertion-sort.go create mode 100644 sorting/go/quick-sort.go diff --git a/scheduling/README.md b/scheduling/README.md index bd30ba55..e679f785 100644 --- a/scheduling/README.md +++ b/scheduling/README.md @@ -3,3 +3,6 @@ ### Python 1. [Interval Scheduling](python/interval-scheduling.py) + +### Golang +1. [Interval Scheduling](go/interval-scheduling.go) diff --git a/scheduling/go/interval-scheduling.go b/scheduling/go/interval-scheduling.go new file mode 100644 index 00000000..c95d02d5 --- /dev/null +++ b/scheduling/go/interval-scheduling.go @@ -0,0 +1,47 @@ +/* + Input: Start and finish time of n jobs + Output: Schedule with maximum number of non overlapping jobs + The Strategy: At each step choose the job with earliest finish time + Algorithm Type: Greedy + Time Complexity: O(n*log(n)) +*/ +package main + +import ( + "fmt" + "sort" +) + +func getOptSchedule(jobs [][]int) []int { + var optSchedule []int + sortedJobs := append([][]int(nil), jobs...) + sort.SliceStable(sortedJobs, func(i, j int) bool { + return sortedJobs[i][2] < sortedJobs[j][2] + }) + n := len(sortedJobs) + optSchedule = append(optSchedule, sortedJobs[0][0]) + for i := 1; i < n; i++ { + last := optSchedule[len(optSchedule)-1] + if sortedJobs[i][1] >= jobs[last][2] { + optSchedule = append(optSchedule, sortedJobs[i][0]) + } + } + return optSchedule +} + +func main() { + jobs := [][]int{ + {0, 2, 8}, // [job_id, start_time, finish_time] + {1, 6, 10}, + {2, 1, 3}, + {3, 4, 7}, + {4, 3, 6}, + {5, 1, 2}, + {6, 8, 10}, + {7, 10, 15}, + {8, 12, 16}, + {9, 14, 16}, + } + optSchedule := getOptSchedule(jobs) + fmt.Println(optSchedule) +} diff --git a/sorting/README.md b/sorting/README.md index 2a904dd7..7cbff5e7 100644 --- a/sorting/README.md +++ b/sorting/README.md @@ -44,3 +44,6 @@ 2. [Insertion Sort](js/insertion-sort.js) 3. [Selection Sort](js/selection-sort.js) +### Golang +1. [Insertion Sort](go/insertion-sort.go) +2. [Quick Sort](go/quick-sort.go) diff --git a/sorting/go/insertion-sort.go b/sorting/go/insertion-sort.go new file mode 100644 index 00000000..9b51738d --- /dev/null +++ b/sorting/go/insertion-sort.go @@ -0,0 +1,34 @@ +/* +* Analogizing this algorithm with inserting a playing +* card into your hand, we distinguish the "key" as +* the inserting card and find the position of that +* card among the previous j - 1 cards. + +* O(n^2) runtime (the deck is sorted in descending order). + */ + +package main + +import ( + "fmt" +) + +func insertionSort(arr []int) { + n := len(arr) + for i := 1; i < n; i++ { + key := arr[i] + j := i - 1 + for j >= 0 && arr[j] > key { + arr[j+1] = arr[j] + j-- + } + arr[j+1] = key + } +} + +func main() { + arr := []int{10, 1, 6, 256, 2, 53, 235, 53, 1, 7, 23} + fmt.Println("Unsorted Array:", arr) + insertionSort(arr) + fmt.Println("Sorted Array:", arr) +} diff --git a/sorting/go/quick-sort.go b/sorting/go/quick-sort.go new file mode 100644 index 00000000..890adede --- /dev/null +++ b/sorting/go/quick-sort.go @@ -0,0 +1,43 @@ +/* + Quick Sort is a divide and conquer algorithm. + First we choose a pivot and split the array in two parts, one containing all elements less than or equal to the pivot and other contains the rest (the pivot element is in neither of them) + Then we recursively sort the two arrays and finally concatenate them to get the sorted array. + Average Time Complexity: O(n*log(n)) + For details explanation and proof of correctness check this -> https://cs.pomona.edu/classes/cs140/pdf/l09-quicksort-proof.pdf +*/ + +package main + +import ( + "fmt" + "math/rand" + "time" +) + +func quickSort(arr []int) []int { + n := len(arr) + if n <= 1 { + return arr + } + rand.Seed(time.Now().UnixNano()) + pivot := rand.Int() % n + var left []int + var right []int + for i := 0; i < n; i++ { + if arr[i] <= arr[pivot] && i != pivot { + left = append(left, arr[i]) + } else if arr[i] > arr[pivot] { + right = append(right, arr[i]) + } + } + leftSorted := quickSort(left) + rightSorted := quickSort(right) + sortedArr := append(leftSorted, arr[pivot]) + sortedArr = append(sortedArr, rightSorted...) + return sortedArr +} + +func main() { + arr := []int{10, 1, 6, 256, 2, 53, 235, 53, 1, 7, 23} + fmt.Printf("Unsorted Array: %v\nSorted Array: %v", arr, quickSort(arr)) +}