diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..2f65dce --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +.DS_Store +.AppleDouble + diff --git a/DynamicProgramming/CoinChange.go b/DynamicProgramming/CoinChange.go new file mode 100644 index 0000000..0587154 --- /dev/null +++ b/DynamicProgramming/CoinChange.go @@ -0,0 +1,34 @@ +/* +Coin Change Problem, Given a set of Coin denominations find the number of ways of making total amount +This problem is much like the problem in GameScoring except that we dont consider the permutations as in GameScoring +For Example in this problem (1,1,2) is the same as (2,1,1) and (1,2,1) +*/ + +package main + +import ("fmt") + +func Max(a,b int) int { + if a>=b { + return a + } + return b +} + +func CoinChange(Amount int, Denomination []int) int { + var CoinAmountArray = make([]int,Amount+1) + CoinAmountArray[0] = 1 + for _, den := range Denomination { + for amt:=den;amt0 { + m[val+nextStep][nextStep] = true + } + } + } + } + // If the last val array is empty we return false, it's because we were not able to reach the last stone + //fmt.Println(m) + lastVal := m[stone[len(stone) - 1]] + if len(lastVal) != 0 { + return true + } + return false +} + +func main() { + //array1 := []int{0,1,3,5,6,8,12,17} + //array1 := []int{0,1,2,3,4,8,9,11} + array1 := []int{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32, + 33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66, + 67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100, + 101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126, + 127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152, + 153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178, + 179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204, + 205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230, + 231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256, + 257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282, + 283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,305,306,307,308,309, + 310,311,312,313,314,315,316,317,318,319,320,321,322,323,324,325,326,327,328,329,330,331,332,333,334,335,336, + 337,338,339,340,341,342,343,344,345,346,347,348,349,350,351,352,353,354,355,356,357,358,359,360,361,362,363, + 364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,380,381,382,383,384,385,386,387,388,389,390, + 391,392,393,394,395,396,397,398,399,400,401,402,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417, + 418,419,420,421,422,423,424,425,426,427,428,429,430,431,432,433,434,435,436,437,438,439,440,441,442,443,444, + 445,446,447,448,449,450,451,452,453,454,455,456,457,458,459,460,461,462,463,464,465,466,467,468,469,470,471, + 472,473,474,475,476,477,478,479,480,481,482,483,484,485,486,487,488,489,490,491,492,493,494,495,496,497,498, + 499,500,501,502,503,504,505,506,507,508,509,510,511,512,513,514,515,516,517,518,519,520,521,522,523,524,525, + 526,527,528,529,530,531,532,533,534,535,536,537,538,539,540,541,542,543,544,545,546,547,548,549,550,551,552, + 553,554,555,556,557,558,559,560,561,562,563,564,565,566,567,568,569,570,571,572,573,574,575,576,577,578,579, + 580,581,582,583,584,585,586,587,588,589,590,591,592,593,594,595,596,597,598,599,600,601,602,603,604,605,606, + 607,608,609,610,611,612,613,614,615,616,617,618,619,620,621,622,623,624,625,626,627,628,629,630,631,632,633, + 634,635,636,637,638,639,640,641,642,643,644,645,646,647,648,649,650,651,652,653,654,655,656,657,658,659,660, + 661,662,663,664,665,666,667,668,669,670,671,672,673,674,675,676,677,678,679,680,681,682,683,684,685,686,687, + 688,689,690,691,692,693,694,695,696,697,698,699,700,701,702,703,704,705,706,707,708,709,710,711,712,713,714, + 715,716,717,718,719,720,721,722,723,724,725,726,727,728,729,730,731,732,733,734,735,736,737,738,739,740,741, + 742,743,744,745,746,747,748,749,750,751,752,753,754,755,756,757,758,759,760,761,762,763,764,765,766,767,768, + 769,770,771,772,773,774,775,776,777,778,779,780,781,782,783,784,785,786,787,788,789,790,791,792,793,794,795, + 796,797,798,799,800,801,802,803,804,805,806,807,808,809,810,811,812,813,814,815,816,817,818,819,820,821,822, + 823,824,825,826,827,828,829,830,831,832,833,834,835,836,837,838,839,840,841,842,843,844,845,846,847,848,849, + 850,851,852,853,854,855,856,857,858,859,860,861,862,863,864,865,866,867,868,869,870,871,872,873,874,875,876, + 877,878,879,880,881,882,883,884,885,886,887,888,889,890,891,892,893,894,895,896,897,898,899,900,901,902,903, + 904,905,906,907,908,909,910,911,912,913,914,915,916,917,918,919,920,921,922,923,924,925,926,927,928,929,930, + 931,932,933,934,935,936,937,938,939,940,941,942,943,944,945,946,947,948,949,950,951,952,953,954,955,956,957, + 958,959,960,961,962,963,964,965,966,967,968,969,970,971,972,973,974,975,976,977,978,979,980,981,982,983,984, + 985,986,987,988,989,990,991,992,993,994,995,996,997,998,999} + + canCros := canCross(array1) + if canCros { + fmt.Println("The Frog can cross the river") + } else { + fmt.Println("The Frog cannot cross the river") + } +} \ No newline at end of file diff --git a/DynamicProgramming/GameScoring.go b/DynamicProgramming/GameScoring.go new file mode 100644 index 0000000..775213b --- /dev/null +++ b/DynamicProgramming/GameScoring.go @@ -0,0 +1,64 @@ +/* +Find the total number of ways a player can score n runs if he can only score runs from an array in a given shot +This is a case of dynamic programming and can be done using two methods: + 1) Memoization using a hash map + 2) Bottom up using an array +This class of problem can be extended to many other problems. This is a very important pattern. +*/ + +package main + +import ("fmt") + +// Recursive Memoization +func GameScoringMemoization(Total int, PossibleRuns []int, MemoizedMap map[int]int) int { + if _,ok := MemoizedMap[Total]; ok { + return MemoizedMap[Total] + } else if Total < 0 { + return 0 + } else { + NumWays := 0 + for _, val := range PossibleRuns { + NumWays += GameScoringMemoization(Total - val, PossibleRuns, MemoizedMap) + } + MemoizedMap[Total] = NumWays + } + return MemoizedMap[Total] +} + +// This approach uses an array to store the result and build on it. Returns the total number of ways +func GameScoringBottomUp(Total int, PossibleRuns []int) int { + var MemoizedArray = []int{1} + // We iterate for i from 0 to Total and find the number of total number of ways to get to each step + // We consider that the number of ways to get to 0 is 1 + for tot:=1;tot= 0 { + NumWays += MemoizedArray[tot - val] + } else { + continue + } + } + MemoizedArray = append(MemoizedArray,NumWays) + } + return MemoizedArray[Total] +} + +func main() { + PossibleRuns := []int{5,6,7} + Total := 11 + + + // Bottom up Approach + NumWaysBottomUp := GameScoringBottomUp(Total, PossibleRuns) + fmt.Println(fmt.Sprintf("Number of ways of getting to %d with possible runs %v and BottomUp Approach is %d",Total,PossibleRuns,NumWaysBottomUp)) + + + // Create a MemoizedMap and pass it to the Memoization Function + var MemoizedMap = make(map[int]int) + MemoizedMap[0] = 1 + NumWaysMemoization := GameScoringMemoization(Total, PossibleRuns, MemoizedMap) + fmt.Println(fmt.Sprintf("Number of ways of getting to %d with possible runs %v and Memoization Approach is %d",Total,PossibleRuns,NumWaysMemoization)) + +} \ No newline at end of file diff --git a/DynamicProgramming/KnapSack.go b/DynamicProgramming/KnapSack.go index b854ad8..f94235d 100644 --- a/DynamicProgramming/KnapSack.go +++ b/DynamicProgramming/KnapSack.go @@ -24,7 +24,7 @@ func KnapSackRecursion(ItemWeight,ItemValue []int,n,c int) int { } } -// Memoized version of the problem, which minimizes recusrsion +// Memoized version of the problem, which minimizes recursion func KnapSackMemoization(MemoizedMap map[string]int,ItemWeight,ItemValue []int,n,c int) int { nc := fmt.Sprintf("%d:%d",n,c) if val,ok := MemoizedMap[nc];ok { diff --git a/DynamicProgramming/MaxSumSubsequenceNonAdjacent.go b/DynamicProgramming/MaxSumSubsequenceNonAdjacent.go new file mode 100644 index 0000000..c826b5a --- /dev/null +++ b/DynamicProgramming/MaxSumSubsequenceNonAdjacent.go @@ -0,0 +1,40 @@ +/* +Maximum Subsequence of Non Adjacent Elements + +Example - [1,3,10,14,-5,-3,2,-2,3] +Output - 22 from elements [3,14,2,3] + +We will use dynamic programming to solve this problem +*/ + +package main + +import ("fmt") + +func Max(a,b int) int { + if a>=b { + return a + } + return b +} + +func MaxSubsequenceNonAdjacent(array []int) int { + var maxSoFarArray = make([]int,len(array)) + maxSoFarArray[0] = array[0] + maxSoFarArray[1] = Max(maxSoFarArray[0],array[1]) + for idx,val := range array { + if (idx == 0 || idx == 1) { + continue + } else { + maxSoFarArray[idx] = Max(maxSoFarArray[idx-1],maxSoFarArray[idx-2]+val) + } + } + return maxSoFarArray[len(array)-1] +} + +func main() { + array := []int{1,6,10,14,-5,-1,2,-1,3} + //array := []int{1,-1,6,-4,2,2} + maxSubsequenceNonAdjacentSum := MaxSubsequenceNonAdjacent(array) + fmt.Println("The Maximum sum of Non adjacent subsequence is:",maxSubsequenceNonAdjacentSum) +} \ No newline at end of file diff --git a/MathAndStats/AllSubset.go b/MathAndStats/AllSubset.go new file mode 100644 index 0000000..6e5d6fb --- /dev/null +++ b/MathAndStats/AllSubset.go @@ -0,0 +1,50 @@ +/* +Find all the subsets of a given set +Two methods will be discussed here +1) Using the bit representation approach +2) Using a recursion tree type of approach +*/ + +package main + +import ("fmt" + "math" +) + +func GetBit(num int,bit uint) uint { + temp := 1 << bit + temp = temp & num + if temp == 0 { + return 0 + } else { + return 1 + } +} + +func AllSubsetsBit(array []int) *[][]int { + var SubsetsArray [][]int + var ArrayLen uint = uint(len(array)) + NumSubsets := math.Pow(float64(2),float64(len(array))) + for i:=0;i val) { + MaxSoFar += val + } else { + MaxSoFar = val + } + if MaxSoFar >= GlobalMax{ + GlobalMax = MaxSoFar + } + } + return GlobalMax +} + +func main() { + array := []int{-5,6,7,1,4,-8,16} + MaxSum := Kadanes(&array) + fmt.Println("Largest Sum in the given contiguous Subarray is:",MaxSum) +} diff --git a/README.md b/README.md index 09f716a..34fbe68 100644 --- a/README.md +++ b/README.md @@ -1 +1,19 @@ -# AlgorithmsGolang \ No newline at end of file +# AlgorithmsGolang + +I started working on this repo as a way to showcase my skills in algorithms and data structures. During the process I realized that there are some common pattern which can be extended to many type of algorithms. Any problem can be converted into one of these base patterns. + +The number of problems I have here is more than the base patterns. + +I have created this repository to provide those important patterns that will help people to prepare for interviews. + +The algorithms here are not comprehensive and the repo is still a work in progress + +## Patterns + +### Dynamic Programming +- Fibonacci Problem +- Frog Jumping Problem +- Coin Change Problem +- Game Scoring Problem + +### \ No newline at end of file diff --git a/StackAndQueue/StackUsingQueue.go b/StackAndQueue/StackUsingQueue.go new file mode 100644 index 0000000..f179ef5 --- /dev/null +++ b/StackAndQueue/StackUsingQueue.go @@ -0,0 +1,43 @@ +/* +Implemet a Stack using Queues + +Method 1: Use two Queues to implement a stack. PUSH:O() POP:O() + +Method 2: Use two Queues to implement a stack. PUSH:O() POP:O() + +"github.com/golang-collections/collections/stack" +type Stack +func New() *Stack +func (this *Stack) Len() int +func (this *Stack) Peek() interface{} +func (this *Stack) Pop() interface{} +func (this *Stack) Push(value interface{}) + +"github.com/golang-collections/go-datastructures/queue" +type Queue +func New(hint int64) *Queue +func (q *Queue) Dispose() +func (q *Queue) Disposed() bool +func (q *Queue) Empty() bool +func (q *Queue) Get(number int64) ([]interface{}, error) +func (q *Queue) Len() int64 +func (q *Queue) Put(items ...interface{}) error +func (q *Queue) TakeUntil(checker func(item interface{}) bool) ([]interface{}, error) + +*/ + +package main + +import ("github.com/golang-collections/go-datastructures/queue" + "github.com/golang-collections/collections/stack" +) + +type StackUsingQueue struct { + // Initialized +} + +func (*) + +func main() { + +} \ No newline at end of file diff --git a/arrays/MergeOverlappingIntervals.go b/arrays/MergeOverlappingIntervals.go new file mode 100644 index 0000000..59a4b8d --- /dev/null +++ b/arrays/MergeOverlappingIntervals.go @@ -0,0 +1,81 @@ +/* +LEET CODE PROBLEM +56. Merge Intervals + +Given a collection of intervals, merge all overlapping intervals. + +Example 1: + +Input: [[1,3],[2,6],[8,10],[15,18]] +Output: [[1,6],[8,10],[15,18]] +Explanation: Since intervals [1,3] and [2,6] overlaps, merge them into [1,6]. +Example 2: + +Input: [[1,4],[4,5]] +Output: [[1,5]] +Explanation: Intervals [1,4] and [4,5] are considerred overlapping. + +APPROACH: +Sort the intervals on Start +Then merge +*/ + +package main + +import ("fmt" + "sort" +) + +// Defining a tuple type to hold the intervals as go doesn't have a tuple by default +type Interval struct { + Start,End int +} + +func SortIntervalsByStart(intervals []Interval) []Interval { + var indexKeyMap = make(map[int]Interval) //Each item is mapped to an index which is the key + var keyIndexMap = make(map[int][]int) //Each key is mapped to multiple indices, the values at these indices contain the intervals + var sortedIntervals []Interval + var keyArray sort.IntSlice + for idx,interval := range intervals { + indexKeyMap[idx] = interval + keyIndexMap[interval.Start] = append(keyIndexMap[interval.Start],idx) + keyArray = append(keyArray,interval.Start) + } + // Sort the key array and iterate over it to create the sorted intervals array + keyArray.Sort() + for _,val := range keyArray { + intervalIdx := keyIndexMap[val][len(keyIndexMap[val])-1] + interval := indexKeyMap[intervalIdx] + keyIndexMap[val] = keyIndexMap[val][:len(keyIndexMap[val])-1] + sortedIntervals = append(sortedIntervals,interval) + } + return sortedIntervals +} + +func MergeOverlappingIntervals(intervals []Interval) []Interval { + // Sort the array based on Start value of each interval + intervals = SortIntervalsByStart(intervals) + if len(intervals) == 0 { + return intervals + } + var master Interval = intervals[0] + var intervalsArray []Interval + for _,val := range intervals { + if (val.Start <= master.End && val.Start >= master.Start && val.End >= master.End) { + master.End = val.End + } else if (val.Start > master.End) { + intervalsArray = append(intervalsArray,master) + master = val + } + } + intervalsArray = append(intervalsArray,master) + return intervalsArray +} + + +func main() { + array := []Interval{{1,5},{0,7},{2,6},{5,8},{4,12},{0,15}} + //fmt.Println(array) + mergedIntervals := MergeOverlappingIntervals(array) + fmt.Println(mergedIntervals) +} \ No newline at end of file diff --git a/arrays/maxInSlidingWindow.go b/arrays/maxInSlidingWindow.go index 372a22d..9e38a8a 100644 --- a/arrays/maxInSlidingWindow.go +++ b/arrays/maxInSlidingWindow.go @@ -62,10 +62,11 @@ func maxInSlidingWindow(arr *[]int,windowSize int) { } func main() { - arr := []int{-4,2,-5,1,-1,6} - - - maxInSlidingWindow(&arr,3) + //arr := []int{-4,2,-5,1,-1,6} + arr := []int{1,3,-1,-3,5,3,6,7} + k := 3 + + maxInSlidingWindow(&arr,k) //fmt.Println(dll) //fmt.Println(l.Front()) diff --git a/arrays/maxSingleSellProfit.go b/arrays/maxSingleSellProfit.go new file mode 100644 index 0000000..0a0b0ee --- /dev/null +++ b/arrays/maxSingleSellProfit.go @@ -0,0 +1,51 @@ +/* +Find maximum single sell profit +Given a list of stock prices for n days, find the maximum profit with a single buy/sell activity. + +Description: +Given a list of day stock prices (integers for simplicity), find the maximum single sell profit. + +We need to maximize the single buy/sell profit and in case we can't make any profit, we'll try to minimize the loss. +For below examples, buy and sell prices for making maximum profit are highlighted. +*/ + +package main + +import ("fmt" + "math" +) + +type BuySell struct { + buy,sell int +} + +func maxSingleSellProfit(array []int) *BuySell { + currentBuy := array[0] + globalSell := array[1] + globalProfit := globalSell - currentBuy + currentProfit := math.MinInt64 + var BS = new(BuySell) + + for i:=1;i globalProfit) { + globalProfit = currentProfit + globalSell = array[i] + } + + if (array[i] < currentBuy) { + currentBuy = array[i] + } + } + BS.buy = globalSell - globalProfit + BS.sell = globalSell + return BS +} + + +func main() { + array := []int{21,12,11,9,6,3} + //array := []int{12,5,9,19} + BS := maxSingleSellProfit(array) + fmt.Println("BuyPrice:",BS.buy,"SellPrice:",BS.sell) +} \ No newline at end of file diff --git a/arrays/mergeSort.go b/arrays/mergeSort.go new file mode 100644 index 0000000..19b28d1 --- /dev/null +++ b/arrays/mergeSort.go @@ -0,0 +1,17 @@ +/* +Sorting an Array through Merge Sort +*/ + +package main + +import ("fmt") + +func MergeSort(array []int) []int { + +} + +func main() { + array := []int{7,2,4,9,10,1,3,1,24,12} + sortedArray := MergeSort(array) + fmt.Println(sortedArray) +} \ No newline at end of file diff --git a/binarySearchTree/BST.go b/binarySearchTree/BST.go new file mode 100644 index 0000000..2886df2 --- /dev/null +++ b/binarySearchTree/BST.go @@ -0,0 +1,133 @@ +/* +Implementation of a binary search tree operations (Insert, Search, Delete) +*/ + +package main + +import ("fmt" + //"container/list" +) + +type Element struct { + + // The value in stored in the element + Value interface{} + left, right *Element + + // The binary search tree to which the element belongs + bst *Bst +} + +type Bst struct { + root Element +} + +// Creates a new Bst Element and initializes it +func New() *Bst { + return new(Bst).Init() +} + +func (b *Bst) Init() *Bst { + b.root.right = nil + b.root.left = nil + return b +} + +func (b *Bst) Insert(val interface{}) { + temp := &b.root + for true { + if (temp.Value == nil) { + temp.Value = val + temp.bst = b + return + } else if (val.(int) >= temp.Value.(int) && temp.right == nil) { + temp.right = new(Element) + temp.right.Value = val + temp.right.bst = b + return + } else if (val.(int) < temp.Value.(int) && temp.left == nil) { + temp.left = new(Element) + temp.left.Value = val + temp.left.bst = b + return + } else if (val.(int) >= temp.Value.(int) && temp.right != nil) { + temp = temp.right + } else { + temp = temp.left + } + } +} + +// Returns if a value exists in the Binary Search Tree +func (b *Bst) Search(val interface{}) bool { + temp := &b.root + for true { + if (temp.Value.(int) == val.(int)) { + return true + } else if (val.(int) >= temp.Value.(int) && temp.right != nil) { + temp = temp.right + } else if (val.(int) < temp.Value.(int) && temp.left != nil) { + temp = temp.left + } else { + return false + } + } + return false +} + +func (b *Bst) Remove(val interface{}) { + +} + +// Inorder Traversal (Left, Root, Right) +func (b *Bst) Inorder(root *Element) { + if (root == nil) { + return + } + b.Inorder(root.left) + fmt.Println(root.Value) + b.Inorder(root.right) +} + +func (b *Bst) Preorder(root *Element) { + if (root == nil) { + return + } + fmt.Println(root.Value) + b.Preorder(root.left) + b.Preorder(root.right) +} + +func (b *Bst) Postorder(root *Element) { + if (root == nil) { + return + } + b.Postorder(root.left) + b.Postorder(root.right) + fmt.Println(root.Value) +} + +func (b *Bst) Levelorder() { + +} + +/* +func ArrayToBST(array []int) { + +} +*/ + +func main() { + // Instantiate a random BST with the root element + array := []int{5,10,12,7,6,21,35,45,22,100} + b := New() + for _, val := range array { + b.Insert(val) + } + fmt.Println(b.Search(7)) + b.Inorder(&b.root) + b.Preorder(&b.root) + b.Postorder(&b.root) + //fmt.Println(b.root) + //fmt.Println(b.root.right) +} diff --git a/linkedList/RotateLinkedList.go b/linkedList/RotateLinkedList.go new file mode 100644 index 0000000..12569a1 --- /dev/null +++ b/linkedList/RotateLinkedList.go @@ -0,0 +1,93 @@ +/* +LEET CODE PROBLEM +61. Rotate List + +Given a linked list, rotate the list to the right by k places, where k is non-negative. + +Example 1: + +Input: 1->2->3->4->5->NULL, k = 2 +Output: 4->5->1->2->3->NULL +Explanation: +rotate 1 steps to the right: 5->1->2->3->4->NULL +rotate 2 steps to the right: 4->5->1->2->3->NULL +Example 2: + +Input: 0->1->2->NULL, k = 4 +Output: 2->0->1->NULL +Explanation: +rotate 1 steps to the right: 2->0->1->NULL +rotate 2 steps to the right: 1->2->0->NULL +rotate 3 steps to the right: 0->1->2->NULL +rotate 4 steps to the right: 2->0->1->NUL +*/ + +package main + +import "fmt" + +type ListNode struct { + Val int + Next *ListNode +} + +func rotateRight(head *ListNode, k int) *ListNode { + listLen := 1 + var n_k int + // make an initial pass through the list and get the length of the list + temp := head + //fmt.Println(temp) + for temp.Next != nil { + listLen++ + temp = temp.Next + } + // This will tell us the real value of k keeping view the list length + k = k%listLen + if listLen == 0 || k == 0 { + return head + } else if (listLen == k) { + return head + } + n_k = listLen - k + + // Traverse n_k elements ahead and sever the connection + temp = head + for i:=0;i pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy