What is wrong with the following merge sort algorithm? - algorithm

As the question states, I'm having trouble finding where is the issue within the following algorithm. It is the aux function for mergesort, i.e. the one used for combining sorted arrays.
func Merge(toSort *[]int, p, q, r int) {
arr := *toSort
L := arr[p:q]
R := arr[q:r+1]
fmt.Println(L)
fmt.Println(R)
i := 0
j := 0
for index := p; index <= r; index++ {
if i >= len(L) {
arr[index] = R[j]
j += 1
continue
} else if j >= len(R) {
arr[index] = L[i]
i += 1
continue
}
if L[i] > R[j] {
fmt.Println("right smaller")
arr[index] = R[j]
j += 1
continue
}
if L[i] <= R[j] {
fmt.Println("left smaller")
arr[index] = L[i]
i += 1
continue
}
}
}
For arr := []int{1,7,14,15,44,65,79,2,3,6,55,70} it gives as output [1 2 2 2 2 2 2 2 3 6 55 70].
Golang Play link
The JavaScript equivalent for this function works as expected, but I don't know why it isn't working in Go
Thank you

Golang slices are passed by reference. So you don't need to pass a pointer into the function in the first place, but you do need to take explicit copies of L and R or else merge into a different slice entirely. You are currently writing into the same underlying memory from which you are getting your values.

Code like L := arr[p:q] does not create a copy. I suppose you are overwriting your L and R parts during the assignments to arr. Have a look at http://blog.golang.org/slices to understand how slices work. (E.g. you'll basically never write stuff like toSort *[]int as []int is almost kinda pointer)
This seems to work: http://play.golang.org/p/vPo2ZKXtI9

You don't need all the indexes: slices are already views into an array. Here's a complete example using purely slice manipulation:
package main
import "fmt"
// Merge takes two sorted, increasing slices of ints and
// returns a slice combining them into a single sorted, increasing
// slice.
func Merge(a, b []int) []int {
res := make([]int, 0, len(a)+len(b))
for len(a) > 0 || len(b) > 0 {
if len(b) == 0 || len(a) > 0 && a[0] <= b[0] {
res = append(res, a[0])
a = a[1:]
} else {
res = append(res, b[0])
b = b[1:]
}
}
return res
}
func main() {
a := []int{1, 2, 5, 6, 3, 4, 7, 9}
fmt.Println(Merge(a[:4], a[4:]))
}

Related

Rotate Array in Go

This is a LeetCode problem: 189. Rotate Array:
Given an array, rotate the array to the right by k steps, where k is
non-negative.
Example 1:
Input: [1,2,3,4,5,6,7] and k = 3
Output: [5,6,7,1,2,3,4]
And here is my solution:
func rotate(nums []int, k int) {
k = k % len(nums)
nums = append(nums[k:],nums[0:k]...)
fmt.Println(nums)
}
It is a straight forward algorithm but it does not work.
I am new to Go. I suppose nums is passed by value and changes to nums won't affect the real nums.
How can I get this right?
In Go, all arguments are passed by value.
A Go slice is represented at runtime by a slice descriptor:
type slice struct {
array unsafe.Pointer
len int
cap int
}
If you change any of the slice descriptor values in a function then communicate the change, typically by returning the changed slice descriptor.
Your rotate function changes the values of the slice num pointer to the underlying array and the slice capacity, so return num.
For example, after I fixed the bugs in your rotate algorithm,
package main
import "fmt"
func rotate(nums []int, k int) []int {
if k < 0 || len(nums) == 0 {
return nums
}
fmt.Printf("nums %p array %p len %d cap %d slice %v\n", &nums, &nums[0], len(nums), cap(nums), nums)
r := len(nums) - k%len(nums)
nums = append(nums[r:], nums[:r]...)
fmt.Printf("nums %p array %p len %d cap %d slice %v\n", &nums, &nums[0], len(nums), cap(nums), nums)
return nums
}
func main() {
nums := []int{1, 2, 3, 4, 5, 6, 7}
fmt.Printf("nums %p array %p len %d cap %d slice %v\n", &nums, &nums[0], len(nums), cap(nums), nums)
nums = rotate(nums, 3)
fmt.Printf("nums %p array %p len %d cap %d slice %v\n", &nums, &nums[0], len(nums), cap(nums), nums)
}
Output:
nums 0xc00000a080 array 0xc00001a1c0 len 7 cap 7 slice [1 2 3 4 5 6 7]
nums 0xc00000a0c0 array 0xc00001a1c0 len 7 cap 7 slice [1 2 3 4 5 6 7]
nums 0xc00000a0c0 array 0xc00001a240 len 7 cap 8 slice [5 6 7 1 2 3 4]
nums 0xc00000a080 array 0xc00001a240 len 7 cap 8 slice [5 6 7 1 2 3 4]
Reference: The Go Blog: Go Slices: usage and internals
Here's a way do rotate a float 32 slice, you can change it for another type.
//RotateF32Slice positive n rotate to the left, negative to right
func RotateF32Slice(slice []float32, n int) (rotateSlice []float32) {
var begin []float32
var end []float32
size := len(slice)
rotateSlice = make([]float32, size)
nAbs := math.Abs(float64(n))
if int(nAbs) > size {
remainder, _ := QuotientAndRemainderF32(float32(n), float32(size))
n = int(remainder)
}
if n != 0 {
if n > 0 {
index := size - n
begin = slice[index:]
end = slice[0:index]
copy(rotateSlice, begin)
copy(rotateSlice[n:], end)
} else {
n = int(nAbs)
index := size - n
begin = slice[n:]
end = slice[0:n]
copy(rotateSlice, begin)
copy(rotateSlice[index:], end)
}
} else {
copy(rotateSlice, slice)
}
return rotateSlice
}
//QuotientAndRemainderF32 Computes the integer quotient and the remainder of the inputs. This function rounds floor(x/y) to the nearest integer towards -inf.
func QuotientAndRemainderF32(x, y float32) (Remainder, Quotient float32) {
Quotient = float32(math.Floor(float64(x / y)))
Remainder = x - y*Quotient
return Remainder, Quotient
}
Solutions
Solution 1 :
func rotate(ar []int,d,n int) []int{
var newArray []int
for i:=0;i<d;i++{
newArray = ar[1:n]
newArray = append(newArray,ar[0])
ar = newArray
}
return ar
}
Solution 2 :
func rotateR(ar []int,d,n int) []int{
ar = append(ar[d:n],ar[0:d]...)
return ar
}
func rotate(nums []int, k int) {
k = k % len(nums)
result := append(nums[len(nums)-k:], nums[:len(nums)-k]...)
for i := 0; i < len(nums); i++ {
nums[i] = result[i]
}
}
Answering this late as i came across this while reading the book "The Go Programming language". It presents a quite elegant algo to use the reverse function and apply it thrice to achieve the desired rotation by k elems. Something like this
// function to rotate array by k elems (3 reverse method)
func rotate(arr []int, k int) {
reverse(arr[:k])
reverse(arr[k:])
reverse(arr)
}
Please note, you will have to write a reverse function. Go does not provide one. This is an O(n) solution and takes O(1) space.
This is my solution to the same hackerrank problem
func rotateLeft(d int32, arr []int32) []int32 {
for ; d > 0 ; d-- {
left := arr[0]
arr = arr[1:]
arr = append(arr, left)
}
return arr
}
for me this worked for many of array rotating but not for hundreds nums[].
func rotate(nums []int, k int) {
for count:=k; count>0; count--{
if len(nums) >= 1 && len(nums) <= 10^5 {
for i:=len(nums)-1; i>0; i--{
nums[i], nums[i-1] = nums[i-1], nums[i]
}
}
}
}
Given an array, rotate the array to the right by k steps, where k is
non-negative.
Example 1:
Input: [1,2,3,4,5,6,7] and k = 3 Output: [5,6,7,1,2,3,4]
Blockquote
First, for k=3, shouldn't be the output [4,5,6,7,1,2,3] ?
For most array operations, it is always simplier to add elements to a newly created array rather than change the source array. If the array is not really large (takes Gigs of memory / billions of items, etc..), you can use a function that adds elements to the newly created array in the order you require and returns new one:
// GO 1.18
func rot[T any](slice []T, k int) (newSlice []T){
l := len(slice)
for i := range slice {
newSlice = append(newSlice, slice[(k+i) % l])
}
return
}
fmt.Printf("Slice %v after rotation %v\n", []int{1,2,3,4,5,6,7}, rot[int]([]int{1,2,3,4,5,6,7}, 3))
//Slice [1 2 3 4 5 6 7] after rotation [4 5 6 7 1 2 3]
If you insist on using "slicing", the code looks like this:
func rotationBySlicing[T any](slice []T, k int) (newSlice []T) {
if len(slice) == 0 {
return slice
}
return append(slice[(k%len(slice)):],slice[0:k%len(slice)]...)
}
fmt.Printf("Array %v after rotation %v\n", []string{}, rotationBySlicing[string]([]string{},1))
fmt.Printf("Array %v after rotation %v\n", []string{"a"}, rotationBySlicing[string]([]string{"a"},1))
fmt.Printf("Array %v after rotation %v\n", []string{"a","b"}, rotationBySlicing[string]([]string{"a","b"},1))
fmt.Printf("Array %v after rotation %v\n", []string{"a","b","c"}, rotationBySlicing[string]([]string{"a","b","c"},1))
fmt.Printf("Array %v after rotation %v\n", []string{"a", "b", "c", "d"}, rotationBySlicing[string]([]string{"a", "b", "c", "d"},1))
fmt.Printf("Slice %v after rotation %v\n", []int{1,2,3,4,5,6,7}, rotationBySlicing[int]([]int{1,2,3,4,5,6,7}, 3))
Array [] after rotation []
Array [a] after rotation [a]
Array [a b] after rotation [b a]
Array [a b c] after rotation [b c a]
Array [a b c d] after rotation [b c d a]
Array [1 2 3 4 5 6 7] after rotation [4 5 6 7 1 2 3]
Also instruction says:
where k is non-negative
, for completeness the code should handle case when k is less than 0
In my case, I preferred this algorithm below because I wanted to keep slice capacity the same:
// Rotation by keeping the capacity same
func Rotate(nums []int, k int) {
k %= len(nums)
new_array := make([]int, len(nums))
copy(new_array[:k], nums[len(nums)-k:])
copy(new_array[k:], nums[:len(nums)-k])
copy(nums, new_array)
}
Also, I tested it in Leet code and it looks good :)
You can also add a condition at the top of your function to make it ready for negative shifts (rotates),
Whole code again:
func Rotate(nums []int, k int) {
k %= len(nums)
// Condition below is added.
if k < 0 {
k += len(nums)
}
new_array := make([]int, len(nums))
copy(new_array[:k], nums[len(nums)-k:])
copy(new_array[k:], nums[:len(nums)-k])
copy(nums, new_array)
}
This doesn't work because []byte is a slice which is sort of a "pointer to an array". Doing:
func f(v []T) {
v = ... //
}
won't have any observable effect for the caller. Assuming your append way is correct (didn't really check it) you could do something like this:
func rotate(nums []int, k int) {
k = k % len(nums)
temp := append(nums[k:], nums[0:k]...)
copy(nums, temp) // this actually writes to where nums points to
}
func main() {
nums := []int{1,2,3,4,5,6,7}
rotate(nums ,3)
fmt.Println(nums)
}

Golang: Find two number index where the sum of these two numbers equals to target number

The problem is: find the index of two numbers that nums[index1] + nums[index2] == target. Here is my attempt in golang (index starts from 1):
package main
import (
"fmt"
)
var nums = []int{0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 25182, 25184, 25186, 25188, 25190, 25192, 25194, 25196} // The number list is too long, I put the whole numbers in a gist: https://gist.github.com/nickleeh/8eedb39e008da8b47864
var target int = 16021
func twoSum(nums []int, target int) (int, int) {
if len(nums) <= 1 {
return 0, 0
}
hdict := make(map[int]int)
for i := 1; i < len(nums); i++ {
if val, ok := hdict[nums[i+1]]; ok {
return val, i + 1
} else {
hdict[target-nums[i+1]] = i + 1
}
}
return 0, 0
}
func main() {
fmt.Println(twoSum(nums, target))
}
The nums list is too long, I put it into a gist:
https://gist.github.com/nickleeh/8eedb39e008da8b47864
This code works fine, but I find the return 0,0 part is ugly, and it runs ten times slower than the Julia translation. I would like to know is there any part that is written terrible and affect the performance?
Edit:
Julia's translation:
function two_sum(nums, target)
if length(nums) <= 1
return false
end
hdict = Dict()
for i in 1:length(nums)
if haskey(hdict, nums[i])
return [hdict[nums[i]], i]
else
hdict[target - nums[i]] = i
end
end
end
In my opinion if no elements found adding up to target, best would be to return values which are invalid indices, e.g. -1. Although returning 0, 0 would be enough as a valid index pair can't be 2 equal indices, this is more convenient (because if you forget to check the return values and you attempt to use the invalid indices, you will immediately get a run-time panic, alerting you not to forget checking the validity of the return values). As so, in my solutions I will get rid of that i + 1 shifts as it makes no sense.
Benchmarking of different solutions can be found at the end of the answer.
If sorting allowed:
If the slice is big and not changing, and you have to call this twoSum() function many times, the most efficient solution would be to sort the numbers simply using sort.Ints() in advance:
sort.Ints(nums)
And then you don't have to build a map, you can use binary search implemented in sort.SearchInts():
func twoSumSorted(nums []int, target int) (int, int) {
for i, v := range nums {
v2 := target - v
if j := sort.SearchInts(nums, v2); v2 == nums[j] {
return i, j
}
}
return -1, -1
}
Note: Note that after sorting, the indices returned will be indices of values in the sorted slice. This may differ from indices in the original (unsorted) slice (which may or may not be a problem). If you do need indices from the original order (original, unsorted slice), you may store sorted and unsorted index mapping so you can get what the original index is. For details see this question:
Get the indices of the array after sorting in golang
If sorting is not allowed:
Here is your solution getting rid of that i + 1 shifts as it makes no sense. Slice and array indices are zero based in all languages. Also utilizing for ... range:
func twoSum(nums []int, target int) (int, int) {
if len(nums) <= 1 {
return -1, -1
}
m := make(map[int]int)
for i, v := range nums {
if j, ok := m[v]; ok {
return j, i
}
m[target-v] = i
}
return -1, -1
}
If the nums slice is big and the solution is not found fast (meaning the i index grows big) that means a lot of elements will be added to the map. Maps start with small capacity, and they are internally grown if additional space is required to host many elements (key-value pairs). An internal growing requires rehashing and rebuilding with the already added elements. This is "very" expensive.
It does not seem significant but it really is. Since you know the max elements that will end up in the map (worst case is len(nums)), you can create a map with a big-enough capacity to hold all elements for the worst case. The gain will be that no internal growing and rehashing will be required. You can provide the initial capacity as the second argument to make() when creating the map. This speeds up twoSum2() big time if nums is big:
func twoSum2(nums []int, target int) (int, int) {
if len(nums) <= 1 {
return -1, -1
}
m := make(map[int]int, len(nums))
for i, v := range nums {
if j, ok := m[v]; ok {
return j, i
}
m[target-v] = i
}
return -1, -1
}
Benchmarking
Here's a little benchmarking code to test execution speed of the 3 solutions with the input nums and target you provided. Note that in order to test twoSumSorted(), you first have to sort the nums slice.
Save this into a file named xx_test.go and run it with go test -bench .:
package main
import (
"sort"
"testing"
)
func BenchmarkTwoSum(b *testing.B) {
for i := 0; i < b.N; i++ {
twoSum(nums, target)
}
}
func BenchmarkTwoSum2(b *testing.B) {
for i := 0; i < b.N; i++ {
twoSum2(nums, target)
}
}
func BenchmarkTwoSumSorted(b *testing.B) {
sort.Ints(nums)
b.ResetTimer()
for i := 0; i < b.N; i++ {
twoSumSorted(nums, target)
}
}
Output:
BenchmarkTwoSum-4 1000 1405542 ns/op
BenchmarkTwoSum2-4 2000 722661 ns/op
BenchmarkTwoSumSorted-4 10000000 133 ns/op
As you can see, making a map with big enough capacity speeds up: it runs twice as fast.
And as mentioned, if nums can be sorted in advance, that is ~10,000 times faster!
If nums is always sorted, you can do a binary search to see if the complement to whichever number you're on is also in the slice.
func binary(haystack []int, needle, startsAt int) int {
pivot := len(haystack) / 2
switch {
case haystack[pivot] == needle:
return pivot + startsAt
case len(haystack) <= 1:
return -1
case needle > haystack[pivot]:
return binary(haystack[pivot+1:], needle, startsAt+pivot+1)
case needle < haystack[pivot]:
return binary(haystack[:pivot], needle, startsAt)
}
return -1 // code can never fall off here, but the compiler complains
// if you don't have any returns out of conditionals.
}
func twoSum(nums []int, target int) (int, int) {
for i, num := range nums {
adjusted := target - num
if j := binary(nums, adjusted, 0); j != -1 {
return i, j
}
}
return 0, 0
}
playground example
Or you can use sort.SearchInts which implements binary searching.
func twoSum(nums []int, target int) (int, int) {
for i, num := range nums {
adjusted := target - num
if j := sort.SearchInts(nums, adjusted); nums[j] == adjusted {
// sort.SearchInts returns the index where the searched number
// would be if it was there. If it's not, then nums[j] != adjusted.
return i, j
}
}
return 0, 0
}

Is this a reasonable and idiomatic GoLang circular shift implementation?

Can anyone comment on whether this is a reasonable and idiomatic way of implementing circular shift of integer arrays in Go? (I deliberately chose not to use bitwise operations.)
How could it be improved?
package main
import "fmt"
func main() {
a := []int{1,2,3,4,5,6,7,8,9,10}
fmt.Println(a)
rotateR(a, 5)
fmt.Println(a)
rotateL(a, 5)
fmt.Println(a)
}
func rotateL(a []int, i int) {
for count := 1; count <= i; count++ {
tmp := a[0]
for n := 1;n < len(a);n++ {
a[n-1] = a[n]
}
a[len(a)-1] = tmp
}
}
func rotateR(a []int, i int) {
for count := 1; count <= i; count++ {
tmp := a[len(a)-1]
for n := len(a)-2;n >=0 ;n-- {
a[n+1] = a[n]
}
a[0] = tmp
}
}
Rotating the slice one position at a time, and repeating to get the total desired rotation means it will take time proportional to rotation distance × length of slice. By moving each element directly into its final position you can do this in time proportional to just the length of the slice.
The code for this is a little more tricky than you have, and you’ll need a GCD function to determine how many times to go through the slice:
func gcd(a, b int) int {
for b != 0 {
a, b = b, a % b
}
return a
}
func rotateL(a []int, i int) {
// Ensure the shift amount is less than the length of the array,
// and that it is positive.
i = i % len(a)
if i < 0 {
i += len(a)
}
for c := 0; c < gcd(i, len(a)); c++ {
t := a[c]
j := c
for {
k := j + i
// loop around if we go past the end of the slice
if k >= len(a) {
k -= len(a)
}
// end when we get to where we started
if k == c {
break
}
// move the element directly into its final position
a[j] = a[k]
j = k
}
a[j] = t
}
}
Rotating a slice of size l right by p positions is equivalent to rotating it left by l − p positions, so you can simplify your rotateR function by using rotateL:
func rotateR(a []int, i int) {
rotateL(a, len(a) - i)
}
Your code is fine for in-place modification.
Don't clearly understand what you mean by bitwise operations. Maybe this
package main
import "fmt"
func main() {
a := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
fmt.Println(a)
rotateR(&a, 4)
fmt.Println(a)
rotateL(&a, 4)
fmt.Println(a)
}
func rotateL(a *[]int, i int) {
x, b := (*a)[:i], (*a)[i:]
*a = append(b, x...)
}
func rotateR(a *[]int, i int) {
x, b := (*a)[:(len(*a)-i)], (*a)[(len(*a)-i):]
*a = append(b, x...)
}
Code works https://play.golang.org/p/0VtiRFQVl7
It's called reslicing in Go vocabulary. Tradeoff is coping and looping in your snippet vs dynamic allocation in this. It's your choice, but in case of shifting 10000 elements array by one position reslicing looks much cheaper.
I like Uvelichitel solution but if you would like modular arithmetic which would be O(n) complexity
package main
func main(){
s := []string{"1", "2", "3"}
rot := 5
fmt.Println("Before RotL", s)
fmt.Println("After RotL", rotL(rot, s))
fmt.Println("Before RotR", s)
fmt.Println("After RotR", rotR(rot,s))
}
func rotL(m int, arr []string) []string{
newArr := make([]string, len(arr))
for i, k := range arr{
newPos := (((i - m) % len(arr)) + len(arr)) % len(arr)
newArr[newPos] = k
}
return newArr
}
func rotR(m int, arr []string) []string{
newArr := make([]string, len(arr))
for i, k := range arr{
newPos := (i + m) % len(arr)
newArr[newPos] = k
}
return newArr
}
If you need to enter multiple values, whatever you want (upd code Uvelichitel)
package main
import "fmt"
func main() {
var N, n int
fmt.Scan(&N)
a := make([]int, N)
for i := 0; i < N; i++ {
fmt.Scan(&a[i])
}
fmt.Scan(&n)
if n > 0 {
rotateR(&a, n%len(a))
} else {
rotateL(&a, (n*-1)%len(a))
}
for _, elem := range a {
fmt.Print(elem, " ")
}
}
func rotateL(a *[]int, i int) {
x, b := (*a)[:i], (*a)[i:]
*a = append(b, x...)
}
func rotateR(a *[]int, i int) {
x, b := (*a)[:(len(*a)-i)], (*a)[(len(*a)-i):]
*a = append(b, x...)
}

Generate all permutations in go

I am looking for a way to generate all possible permutations of a list of elements. Something similar to python's itertools.permutations(arr)
permutations ([])
[]
permutations ([1])
[1]
permutations ([1,2])
[1, 2]
[2, 1]
permutations ([1,2,3])
[1, 2, 3]
[1, 3, 2]
[2, 1, 3]
[2, 3, 1]
[3, 1, 2]
[3, 2, 1]
With the difference that I do not care whether permutations would be generated on demand (like a generator in python) or all together. I also do not care whether they will be lexicographically sorted. All I need is to somehow get these n! permutations.
There are a lot of the algorithms that generate permutations. One of the easiest I found is Heap's algorithm:
It generates each permutation from the previous one by choosing a pair
of elements to interchange.
The idea and a pseudocode that prints the permutations one after another is outlined in the above link. Here is my implementation of the algorithm which returns all permutations
func permutations(arr []int)[][]int{
var helper func([]int, int)
res := [][]int{}
helper = func(arr []int, n int){
if n == 1{
tmp := make([]int, len(arr))
copy(tmp, arr)
res = append(res, tmp)
} else {
for i := 0; i < n; i++{
helper(arr, n - 1)
if n % 2 == 1{
tmp := arr[i]
arr[i] = arr[n - 1]
arr[n - 1] = tmp
} else {
tmp := arr[0]
arr[0] = arr[n - 1]
arr[n - 1] = tmp
}
}
}
}
helper(arr, len(arr))
return res
}
and here is an example of how to use it (Go playground):
arr := []int{1, 2, 3}
fmt.Println(permutations(arr))
[[1 2 3] [2 1 3] [3 2 1] [2 3 1] [3 1 2] [1 3 2]]
One thing to notice that the permutations are not sorted lexicographically (as you have seen in itertools.permutations). If for some reason you need it to be sorted, one way I have found it is to generate them from a factorial number system (it is described in permutation section and allows to quickly find n-th lexicographical permutation).
P.S. you can also take a look at others people code here and here
Here's code that iterates over all permutations without generating them all first. The slice p keeps the intermediate state as offsets in a Fisher-Yates shuffle algorithm. This has the nice property that the zero value for p describes the identity permutation.
package main
import "fmt"
func nextPerm(p []int) {
for i := len(p) - 1; i >= 0; i-- {
if i == 0 || p[i] < len(p)-i-1 {
p[i]++
return
}
p[i] = 0
}
}
func getPerm(orig, p []int) []int {
result := append([]int{}, orig...)
for i, v := range p {
result[i], result[i+v] = result[i+v], result[i]
}
return result
}
func main() {
orig := []int{11, 22, 33}
for p := make([]int, len(orig)); p[0] < len(p); nextPerm(p) {
fmt.Println(getPerm(orig, p))
}
}
var res [][]int
func permute(nums []int) [][]int {
res=make([][]int,0)
n:=len(nums)
var backTrack func(int)
backTrack=func(first int){
if first == n{
temp:=make([]int, n)
copy(temp,nums)
res = append(res, temp)
}
for i:=first;i<n;i++{
nums[first],nums[i] = nums[i],nums[first]
backTrack(first+1)
nums[first],nums[i] = nums[i],nums[first]
}
}
backTrack(0)
return res
}
In my case I had a reference to an array, then I've did a few changes in your example:
func generateIntPermutations(array []int, n int, result *[][]int) {
if n == 1 {
dst := make([]int, len(array))
copy(dst, array[:])
*result = append(*result, dst)
} else {
for i := 0; i < n; i++ {
generateIntPermutations(array, n-1, result)
if n%2 == 0 {
// Golang allow us to do multiple assignments
array[0], array[n-1] = array[n-1], array[0]
} else {
array[i], array[n-1] = array[n-1], array[i]
}
}
}
}
numbers := []int{0, 1, 2}
var result [][]int
generateIntPermutations(numbers, len(numbers), &result)
// result -> [[0 1 2] [1 0 2] [2 1 0] [1 2 0] [2 0 1] [0 2 1]]
Another Working code
package permutations
import "fmt"
func AllPermutation(a []int) {
var res [][]int
calPermutation(a, &res, 0)
fmt.Println(res)
}
func calPermutation(arr []int, res *[][]int, k int) {
for i := k; i < len(arr); i++ {
swap(arr, i, k)
calPermutation(arr, res, k+1)
swap(arr, k, i)
}
if k == len(arr)-1 {
r := make([]int, len(arr))
copy(r, arr)
*res = append(*res, r)
return
}
}
func swap(arr []int, i, k int) {
arr[i], arr[k] = arr[k], arr[i]
}
//result [[1 2 3] [1 3 2] [2 1 3] [2 3 1] [3 2 1] [3 1 2]]
Here is another variation:
// heap algorithm
func permutations(arr []int, l int, p [][]int) [][]int {
if l == 1 { p = append(p, append([]int{}, arr...)) }
for i := 0 ; i < l ; i++ {
p = permutations(arr, l-1, p)
if l % 2 == 1 {
arr[0], arr[l-1] = arr[l-1], arr[0]
} else {
arr[i], arr[l-1] = arr[l-1], arr[i]
}
}
return p
}

How to remove items from a slice while ranging over it?

What is the best way to remove items from a slice while ranging over it?
For example:
type MultiDataPoint []*DataPoint
func (m MultiDataPoint) Json() ([]byte, error) {
for i, d := range m {
err := d.clean()
if ( err != nil ) {
//Remove the DP from m
}
}
return json.Marshal(m)
}
As you have mentioned elsewhere, you can allocate new memory block and copy only valid elements to it. However, if you want to avoid the allocation, you can rewrite your slice in-place:
i := 0 // output index
for _, x := range s {
if isValid(x) {
// copy and increment index
s[i] = x
i++
}
}
// Prevent memory leak by erasing truncated values
// (not needed if values don't contain pointers, directly or indirectly)
for j := i; j < len(s); j++ {
s[j] = nil
}
s = s[:i]
Full example: http://play.golang.org/p/FNDFswPeDJ
Note this will leave old values after index i in the underlying array, so this will leak memory until the slice itself is garbage collected, if values are or contain pointers. You can solve this by setting all values to nil or the zero value from i until the end of the slice before truncating it.
I know its answered long time ago but i use something like this in other languages, but i don't know if it is the golang way.
Just iterate from back to front so you don't have to worry about indexes that are deleted. I am using the same example as Adam.
m = []int{3, 7, 2, 9, 4, 5}
for i := len(m)-1; i >= 0; i-- {
if m[i] < 5 {
m = append(m[:i], m[i+1:]...)
}
}
There might be better ways, but here's an example that deletes the even values from a slice:
m := []int{1,2,3,4,5,6}
deleted := 0
for i := range m {
j := i - deleted
if (m[j] & 1) == 0 {
m = m[:j+copy(m[j:], m[j+1:])]
deleted++
}
}
Note that I don't get the element using the i, d := range m syntax, since d would end up getting set to the wrong elements once you start deleting from the slice.
Here is a more idiomatic Go way to remove elements from slices.
temp := s[:0]
for _, x := range s {
if isValid(x) {
temp = append(temp, x)
}
}
s = temp
Playground link: https://play.golang.org/p/OH5Ymsat7s9
Note: The example and playground links are based upon #tomasz's answer https://stackoverflow.com/a/20551116/12003457
One other option is to use a normal for loop using the length of the slice and subtract 1 from the index each time a value is removed. See the following example:
m := []int{3, 7, 2, 9, 4, 5}
for i := 0; i < len(m); i++ {
if m[i] < 5 {
m = append(m[:i], m[i+1:]...)
i-- // -1 as the slice just got shorter
}
}
I don't know if len() uses enough resources to make any difference but you could also run it just once and subtract from the length value too:
m := []int{3, 7, 2, 9, 4, 5}
for i, s := 0, len(m); i < s; i++ {
if m[i] < 5 {
m = append(m[:i], m[i+1:]...)
s--
i--
}
}
Something like:
m = append(m[:i], m[i+1:]...)
You don't even need to count backwards but you do need to check that you're at the end of the array where the suggested append() will fail. Here's an example of removing duplicate positive integers from a sorted list:
// Remove repeating numbers
numbers := []int{1, 2, 3, 3, 4, 5, 5}
log.Println(numbers)
for i, numbersCount, prevNum := 0, len(numbers), -1; i < numbersCount; numbersCount = len(numbers) {
if numbers[i] == prevNum {
if i == numbersCount-1 {
numbers = numbers[:i]
} else {
numbers = append(numbers[:i], numbers[i+1:]...)
}
continue
}
prevNum = numbers[i]
i++
}
log.Println(numbers)
Playground: https://play.golang.org/p/v93MgtCQsaN
I just implement a method which removes all nil elements in slice.
And I used it to solve a leetcode problems, it works perfectly.
/**
* Definition for singly-linked list.
* type ListNode struct {
* Val int
* Next *ListNode
* }
*/
func removeNil(lists *[]*ListNode) {
for i := 0; i < len(*lists); i++ {
if (*lists)[i] == nil {
*lists = append((*lists)[:i], (*lists)[i+1:]...)
i--
}
}
}
You can avoid memory leaks, as suggested in #tomasz's answer, controlling the capacity of the underlying array with a full slice expression. Look at the following function that remove duplicates from a slice of integers:
package main
import "fmt"
func removeDuplicates(a []int) []int {
for i, j := 0, 1; i < len(a) && j < len(a); i, j = i+1, j+1 {
if a[i] == a[j] {
copy(a[j:], a[j+1:])
// resize the capacity of the underlying array using the "full slice expression"
// a[low : high : max]
a = a[: len(a)-1 : len(a)-1]
i--
j--
}
}
return a
}
func main() {
a := []int{2, 3, 3, 3, 6, 9, 9}
fmt.Println(a)
a = removeDuplicates(a)
fmt.Println(a)
}
// [2 3 3 3 6 9 9]
// [2 3 6 9]
For reasons #tomasz has explained, there are issues with removing in place. That's why it is practice in golang not to do that, but to reconstruct the slice. So several answers go beyond the answer of #tomasz.
If elements should be unique, it's practice to use the keys of a map for this. I like to contribute an example of deletion by use of a map.
What's nice, the boolean values are available for a second purpose. In this example I calculate Set a minus Set b. As Golang doesn't have a real set, I make sure the output is unique. I use the boolean values as well for the algorithm.
The map gets close to O(n). I don't know the implementation. append() should be O(n). So the runtime is similar fast as deletion in place. Real deletion in place would cause a shifting of the upper end to clean up. If not done in batch, the runtime should be worse.
In this special case, I also use the map as a register, to avoid a nested loop over Set a and Set b to keep the runtime close to O(n).
type Set []int
func differenceOfSets(a, b Set) (difference Set) {
m := map[int]bool{}
for _, element := range a {
m[element] = true
}
for _, element := range b {
if _, registered := m[element]; registered {
m[element] = false
}
}
for element, present := range m {
if present {
difference = append(difference, element)
}
}
return difference
}
Try Sort and Binary search.
Example:
package main
import (
"fmt"
"sort"
)
func main() {
// Our slice.
s := []int{3, 7, 2, 9, 4, 5}
// 1. Iterate over it.
for i, v := range s {
func(i, v int) {}(i, v)
}
// 2. Sort it. (by whatever condition of yours)
sort.Slice(s, func(i, j int) bool {
return s[i] < s[j]
})
// 3. Cut it only once.
i := sort.Search(len(s), func(i int) bool { return s[i] >= 5 })
s = s[i:]
// That's it!
fmt.Println(s) // [5 7 9]
}
https://play.golang.org/p/LnF6o0yMJGT

Resources