I'm writing a function that returns the vertical order traversal of a binary tree's node values. (ie, from top to bottom, column by column). Here's an example of expected input and output:
Input: [3,9,8,4,0,1,7,null,null,null,2,5] (0's right child is 2 and 1's left child is 5)
3
/\
/ \
9 8
/\ /\
/ \/ \
4 01 7
/\
/ \
5 2
Output:
[
[4],
[9,5],
[3,0,1],
[8,2],
[7]
]
My function outputs everything as expected except for [8,2]—I'm getting [2,8] instead:
[[4] [9 5] [3 0 1] [2 8] [7]]
This is what my function looks like:
func verticalOrder(root *TreeNode) [][]int {
if root == nil {
return [][]int{}
}
var (
hd int
m map[int][]int
vals [][]int
min int
max int
traverse func(t *TreeNode, hd int, m map[int][]int)
)
m = make(map[int][]int)
min = 0
max = 0
traverse = func(t *TreeNode, hd int, m map[int][]int) {
if t == nil {
return
}
m[hd] = append(m[hd], t.Val)
if max < hd {
max = hd
}
if min > hd {
min = hd
}
traverse(t.Left, hd-1, m)
traverse(t.Right, hd+1, m)
}
traverse(root, hd, m)
for i := min; i <= max; i++ {
vals = append(vals, m[i])
}
return vals
}
Essentially, I'm using a hash map to keep track of nodes with the same horizontal distance, and appending them to an array. What I'm trying to figure out is how come my output works properly with 9 and 5 but not with 8 and 2? Any feedback is much appreciated!
Steps to reproduce
Run the code below. You'll get an output of [[4] [9 5] [3 0 1] [2 8] [7]]; the output should be [[4] [9 5] [3 0 1] [8 2] [7]]. The thing that's tripping me up is [9 5] is appending in the correct, vertical order, whereas [2 8] is not despite being similar, so I'm not too sure where to go from here.
package main
import "fmt"
// TreeNode is a binary tree node.
type TreeNode struct {
Val int
Left *TreeNode
Right *TreeNode
}
func verticalOrder(root *TreeNode) [][]int {
if root == nil {
return [][]int{}
}
var (
hd int
m map[int][]int
vals [][]int
min int
max int
traverse func(t *TreeNode, hd int, m map[int][]int)
)
m = make(map[int][]int)
min = 0
max = 0
traverse = func(t *TreeNode, hd int, m map[int][]int) {
if t == nil {
return
}
m[hd] = append(m[hd], t.Val)
if max < hd {
max = hd
}
if min > hd {
min = hd
}
traverse(t.Left, hd-1, m)
traverse(t.Right, hd+1, m)
}
traverse(root, hd, m)
for i := min; i <= max; i++ {
vals = append(vals, m[i])
}
return vals
}
func main() {
root := &TreeNode{
Val: 3,
Left: &TreeNode{
Val: 9,
Left: &TreeNode{
Val: 4,
Left: nil,
Right: nil,
},
Right: &TreeNode{
Val: 0,
Left: nil,
Right: &TreeNode{
Val: 2,
Left: nil,
Right: nil,
},
},
},
Right: &TreeNode{
Val: 8,
Left: &TreeNode{
Val: 1,
Left: &TreeNode{
Val: 5,
Left: nil,
Right: nil,
},
Right: nil,
},
Right: &TreeNode{
Val: 7,
Left: nil,
Right: nil,
},
},
}
fmt.Println(verticalOrder(root))
}
I has nothing to do with append.
You are doing a DFS-traversal of a binary tree, the order is called DFS-order of that tree. Thing is that the DFS-order of the tree is not from top to bottom.
Your code visit node 2 before node 8, so the code m[hd] = append(m[hd], t.Val) makes [2 8] instead of [8 2]. There is nothing inconsistent.
To fix the problem, you can either use a BFS to traverse the tree, or, you can keep the depth info into m and sort each m[hd] accordingly.
Generally speaking, BFS is a better idea, but a sort is quickly hackable.
Related
I'm trying to analyze sparse matrices. Faced with the task of sorting rows in ascending order of the elements in them in the original matrix.
But I don't understand how to do this without damaging the empty elements.
I tried to bind the elements of the sum array to the rows and somehow move them. But some elements have been removed from the CSC structure.
It may be necessary to change the li/lj arrays themselves, but I don't have enough mathematical knowledge for this. More precisely, I don't understand how to track when elements should be rearranged unless additional elements (zeros) are explicitly specified in the structure.
package main
import (
"fmt"
)
type CSC struct {
a, lj, li []int
}
func getEl(i, j int, el *CSC) int {
for k := el.lj[j]; k < el.lj[j+1]; k++ {
if el.li[k] == i {
return el.a[k]
}
}
return 0
}
func maxSliceEl(lj []int) int {
max := 0
for _, v := range lj {
if v > max {
max = v
}
}
return max
}
func main() {
ma := CSC{
a: []int{8, 2, 5, 7, 1, 9, 2},
li: []int{0, 0, 1, 4, 4, 6, 4},
lj: []int{0, 1, 1, 4, 6, 7},
}
n := len(ma.lj) + 1
m := maxSliceEl(ma.li) - 1
fmt.Printf("Col: %v, Row: %v\n", n, m)
maxStr := []int{}
fmt.Println("Initial matrix:")
for i := 0; i < n; i++ {
sumStrEl := 0
for j := 0; j < m; j++ {
fmt.Print(getEl(i, j, &ma), " ")
sumStrEl += getEl(i, j, &ma)
}
maxStr = append(maxStr, sumStrEl)
fmt.Println("|sumStrEl: ", sumStrEl)
}
}
I found a solution to the problem by taking the structure as a solution: the sum of the elements + their index. The solution turned out to be simpler than expected, only the practice of solving sparse matrices was lacking. The position [i] of the sum must be passed to the getEl function as the first parameter.
package main
import (
"fmt"
"sort"
)
// Creating a CSC (CCS) matrix structure
type CSC struct {
// Array of values, column indexes, row indexing
a, lj, li []int
}
// Getting access to the element
func getEl(i, j int, el *CSC) int {
for k := el.lj[j]; k < el.lj[j+1]; k++ {
// If the element string is equal to the string of the searched element, then the element is found
if el.li[k] == i {
return el.a[k]
}
}
// Otherwise, we will return 0. It will be entered into the matrix
return 0
}
func maxSliceEl(lj []int) int {
max := 0
for _, v := range lj {
if v > max {
max = v
}
}
return max
}
type strInfo struct {
summa int
pos int
}
func main() {
// Set the CSC matrix
ma := CSC{
a: []int{8, 2, 5, 7, 1, 9, 2},
li: []int{0, 0, 1, 4, 4, 6, 4},
lj: []int{0, 1, 1, 4, 6, 7},
}
// Define the number of columns
n := len(ma.lj) + 1
// Define the number of rows
m := maxSliceEl(ma.li) - 1
fmt.Printf("Cols: %v, Rows: %v\n", m, n)
// Set a variable with a structure type for calculating
// the amount in a row and indexing each element in it
var stringsInfo []strInfo
fmt.Println("Initial matrix:")
for i := 0; i < n; i++ {
sumStrEl := 0
for j := 0; j < m; j++ {
sumStrEl += getEl(i, j, &ma)
fmt.Print(getEl(i, j, &ma), " ")
}
fmt.Println("|", sumStrEl)
// Adding a cell with the sum and index to the slice
var strI strInfo
strI.summa = sumStrEl
strI.pos = i
stringsInfo = append(stringsInfo, strI)
}
fmt.Println("stringsInfo: ", stringsInfo)
// Sorting the stringsInfo slice in ascending order of the sum elements
sort.Slice(stringsInfo, func(i, j int) (less bool) {
return stringsInfo[i].summa < stringsInfo[j].summa
})
fmt.Println("stringsInfo: ", stringsInfo)
fmt.Println("Sorted matrix:")
for i := range stringsInfo {
for j := 0; j < m; j++ {
// Output the matrix by idnex stringsInfo[i].pos
fmt.Print(getEl(stringsInfo[i].pos, j, &ma), " ")
}
fmt.Println("|", stringsInfo[i].summa)
}
}
i'm trying to do sorting for my slice child's (inside a slice), my slice is created from
var s [][]int64
s = append(s, []int64{2, 60, 55, 5})
s = append(s, []int64{4, 45, 35, 10})
s = append(s, []int64{1, 200, 160, 40})
fmt.Println(s) # [[2 60 55 5] [4 45 35 10] [1 200 160 40]]
how to sort it's value by first element to become :
[[1 200 160 40] [2 60 55 5] [4 45 35 10]]
The question does not state what should be done with empty slices, so treating them like an empty word in a conventional word-sort, would put them first, so this would handle that edge case:
import "sort"
sort.Slice(s, func(i, j int) bool {
// edge cases
if len(s[i]) == 0 && len(s[j]) == 0 {
return false // two empty slices - so one is not less than other i.e. false
}
if len(s[i]) == 0 || len(s[j]) == 0 {
return len(s[i]) == 0 // empty slice listed "first" (change to != 0 to put them last)
}
// both slices len() > 0, so can test this now:
return s[i][0] < s[j][0]
})
Playground version.
func slicesort(arr [][]int){
sort.Slice(arr, func(i, j int) bool{
if arr[i][1]>arr[j][1]{
return true
}
if arr[i][1]==arr[j][1] && arr[i][0]<arr[j][0]{
return true
}
return false
})
}
func main() {
s :=[][]int{{2,8},{2,9},{3,8},{1,9},{3,9}}
slicesort(s)
fmt.Println(s)
}
I am new to Go and doing a few exercises. One of them is to sort the numbers in an array by frequency, from most to least frequent.
Example:
Input: [2, 2, 5, 7, 4, 4, 4, 7, 2]
Output: [2, 4, 7, 5]
Note that [4, 2, 7, 5] would also be correct, since 4 and 2 have the same frequency.
For this purpose I am converting the array into a value value map, which here would look like this: [2:3][4:3][7:2][5:1] (2 and 3 have freq. of 3, 7 has the freq of 2,... )
Afterwards I would like to simply loop through the map and output the keys ordered by value. For that I use the following code, which apparently does not work. Why?
count := 0
max := -1
// break loop, if map is empty
for i := 0; i < 1; i-- {
if len(m) == 0 {
break
}
max = -1
// get key of biggest value
for k, v := range m {
if v > max {
max = k
}
}
// res (for result) is a slice of integers
res[count] = max
// remove key-value-pair from map
delete(m, max)
count++
}
return res
Please keep in mind that this is an exercise. I am very sure there are much better, build in ways to do this.
Your 'max' variable is meant to keep track of the maximum frequency seen so far. However when you do 'max = k' you're assigning a key.
You need to keep track of the maximum frequency and the key associated with that frequency in separate variables.
...
for k, v := range m {
if v > maxFreq {
maxFreq = v
mostFrequentKey = k
}
}
// res (for result) is a slice of integers
res[count] = mostFrequentKey
// remove key-value-pair from map
delete(m, mostFrequentKey)
count++
...
For sorted frequencies, use a map then a slice. For example,
package main
import (
"fmt"
"sort"
)
func main() {
Input := []int{2, 2, 5, 7, 4, 4, 4, 7, 2}
fmt.Println("Input: ", Input)
mFreq := make(map[int]int, len(Input))
for _, n := range Input {
mFreq[n]++
}
sFreq := make([][2]int, 0, len(mFreq))
for n, f := range mFreq {
sFreq = append(sFreq, [2]int{n, f})
}
sort.Slice(sFreq, func(i, j int) bool {
if sFreq[i][1] <= sFreq[j][1] {
if sFreq[i][1] < sFreq[j][1] {
return false
}
if sFreq[i][0] >= sFreq[j][0] {
return false
}
}
return true
},
)
Output := []int{2, 4, 7, 5}
fmt.Println("Output: ", Output)
fmt.Println("Frequencies:", sFreq)
}
Playground: https://play.golang.org/p/8tiSksz3S76
Output:
Input: [2 2 5 7 4 4 4 7 2]
Output: [2 4 7 5]
Frequencies: [[2 3] [4 3] [7 2] [5 1]]
I have an array like:
a:= [1,2,3,4,5]
b:= [5,6,7,8,9]
How to know array b have contain element in array a without using foreach?
How to know array b have contain element in array a without using foreach?
You can't. And you should not try as this is pointless restriction.
If the arrays are sorted (as they appear to be in your question) there is an algorithm that works better than going through each element.
Pick the first element of a, call it x.
Binary search b for the first element equal or greater than x. If they are equal, you found an element that is contained in both arrays, if not, make that your new x. Now search a for x in the same way. Repeat until you run out of elements in one of the arrays.
This can be trivially extended to an arbitrary number of arrays (in fact, it's easier to write with an arbitrary number of arrays).
Here's a quick and dirty implementation:
package main
import (
"fmt"
"sort"
)
func inter(arrs ...[]int) []int {
res := []int{}
x := arrs[0][0]
i := 1
for {
off := sort.SearchInts(arrs[i], x)
if off == len(arrs[i]) {
// we emptied one slice, we're done.
break
}
if arrs[i][off] == x {
i++
if i == len(arrs) {
// x was in all the slices
res = append(res, x)
x++ // search for the next possible x.
i = 0
}
} else {
x = arrs[i][off]
i = 0 // This can be done a bit more optimally.
}
}
return res
}
func main() {
a := []int{1, 2, 3, 4, 5, 7}
b := []int{5, 6, 7, 8, 9}
fmt.Println(inter(a, b))
}
package main
import (
set "github.com/deckarep/golang-set"
)
func array_intersect(a, b []interface{}) []interface{} {
return set.NewSetFromSlice(a).Intersect(set.NewSetFromSlice(b)).ToSlice()
}
func main() {
a := []interface{}{1, 2, 3, 4, 5, 7}
b := []interface{}{5, 6, 7, 8, 9}
println(array_intersect(a, b))
}
package main
import (
"fmt"
"sort"
)
func array_intersect(a, b []int) []int {
ret := []int{}
lenA := len(a)
lenB := len(b)
if lenA == 0 || lenB == 0 {
return ret
}
sort.Ints(a)
sort.Ints(b)
var i, j int
for {
a = a[i:]
if i = sort.SearchInts(a, b[j]); i >= len(a) {
break
}
if a[i] == b[j] {
ret = append(ret, a[i])
}
if j++; j >= lenB {
break
}
}
return ret
}
func main() {
a := []int{5, 7, 1, 1, 2, 3, 4, 5, 7}
b := []int{1, 1, 5, 6, 7, 8, 9}
fmt.Printf("a=%v, b=%v", a, b)
fmt.Printf("%v\n", array_intersect(a, b))
fmt.Printf("a=%v, b=%v", a, b)
}
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
}