Skip to content
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
34 changes: 34 additions & 0 deletions dynamic/climbingstairs.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package dynamic

// ClimbingStairs calculates the number of distinct ways to climb
// n stairs when each step can be either 1 or 2 stairs.
//
// It uses dynamic programming with two variables to optimize
// space complexity.
//
// Time complexity: O(n)
// Space complexity: O(1)
//
// Returns 1 for n = 0 and 0 for negative values of n.
//
// Note: The result may overflow int for sufficiently large n.
func ClimbingStairs(n int) int {
if n < 0 {
return 0
}

if n <= 1 {
return 1
}

prevTwo := 1
prevOne := 1

for i := 2; i <= n; i++ {
current := prevOne + prevTwo
prevTwo = prevOne
prevOne = current
}

return prevOne
}
51 changes: 51 additions & 0 deletions dynamic/climbingstairs_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package dynamic_test

import (
"fmt"
"testing"

"github.com/TheAlgorithms/Go/dynamic"
)

func TestClimbingStairs(t *testing.T) {
td := []struct {
n int
expected int
}{
{0, 1},
{1, 1},
{2, 2},
{3, 3},
{4, 5},
{5, 8},
{6, 13},
{7, 21},
{10, 89},
{15, 987},
{20, 10946},
{-1, 0},
{-5, 0},
}

for _, tc := range td {
name := fmt.Sprintf("ClimbingStairs(%d)", tc.n)

t.Run(name, func(t *testing.T) {
actual := dynamic.ClimbingStairs(tc.n)

if actual != tc.expected {
t.Errorf(
"ClimbingStairs(%d) = %d, expected %d",
tc.n,
actual,
tc.expected,
)
}
})
}
}

func ExampleClimbingStairs() {
fmt.Print(dynamic.ClimbingStairs(4))
// Output: 5
}
33 changes: 33 additions & 0 deletions dynamic/maxnonadjacentsum.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package dynamic

// MaxNonAdjacentSum finds the maximum sum of non-adjacent elements
// in a given slice of integers.
//
// The algorithm uses dynamic programming with two variables to
// optimize space complexity.
//
// Time complexity: O(n)
// Space complexity: O(1)
//
// The empty subset is allowed, so the function returns 0 for
// an empty slice or a slice containing only negative numbers.
func MaxNonAdjacentSum(nums []int) int {
if len(nums) == 0 {
return 0
}

prevTwo := 0
prevOne := 0

for _, num := range nums {
current := prevOne
if prevTwo+num > current {
current = prevTwo + num
}

prevTwo = prevOne
prevOne = current
}

return prevOne
}
53 changes: 53 additions & 0 deletions dynamic/maxnonadjacentsum_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package dynamic_test

import (
"fmt"
"testing"

"github.com/TheAlgorithms/Go/dynamic"
)

func TestMaxNonAdjacentSum(t *testing.T) {
td := []struct {
input []int
expected int
}{
{[]int{}, 0},
{[]int{5}, 5},
{[]int{-5}, 0},
{[]int{2, 7, 9, 3, 1}, 12},
{[]int{1, 2, 3, 4, 5}, 9},
{[]int{2, 1, 4, 9}, 11},
{[]int{10, 20}, 20},
{[]int{-2, -7, -3}, 0},
{[]int{4, -1, 5, -2, 6}, 15},
{[]int{5, 5, 10, 100, 10, 5}, 110},
{[]int{0, 0, 0, 0}, 0},
{[]int{100, 1, 1, 100}, 200},
}

for _, tc := range td {
name := fmt.Sprintf(
"MaxNonAdjacentSum(%v)",
tc.input,
)

t.Run(name, func(t *testing.T) {
actual := dynamic.MaxNonAdjacentSum(tc.input)

if actual != tc.expected {
t.Errorf(
"MaxNonAdjacentSum(%v) = %d, expected %d",
tc.input,
actual,
tc.expected,
)
}
})
}
}

func ExampleMaxNonAdjacentSum() {
fmt.Print(dynamic.MaxNonAdjacentSum([]int{2, 7, 9, 3, 1}))
// Output: 12
}