feat(Go-Tool):2021/03/26: 新增全排列的递归实现、字典序实现、递增进制位实现、递减进制位实现
This commit is contained in:
@@ -81,6 +81,8 @@
|
|||||||
|
|
||||||
2021/03/18:新增超过半数数字系列算法题,新增出现次数不同的数字系列算法题
|
2021/03/18:新增超过半数数字系列算法题,新增出现次数不同的数字系列算法题
|
||||||
|
|
||||||
|
2021/03/26: 新增全排列的递归实现、字典序实现、递增进制位实现、递减进制位实现
|
||||||
|
|
||||||
# 修复日志
|
# 修复日志
|
||||||
2020/11/23:修改项目案例(按照一定规则对一组数据进行排序分组)
|
2020/11/23:修改项目案例(按照一定规则对一组数据进行排序分组)
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,56 @@
|
|||||||
|
/*
|
||||||
|
* @Author : huangzj
|
||||||
|
* @Time : 2021/3/22 15:29
|
||||||
|
* @Description:
|
||||||
|
*/
|
||||||
|
|
||||||
|
package FullPermutation
|
||||||
|
|
||||||
|
import (
|
||||||
|
sort2 "Go-Tool/util/sort"
|
||||||
|
)
|
||||||
|
|
||||||
|
//字典序获取全排列
|
||||||
|
func (per *Permutation) DictionaryOrder(b []byte) {
|
||||||
|
//先排序
|
||||||
|
sort2.QuickSortByte(b, 0, len(b)-1)
|
||||||
|
for {
|
||||||
|
bef := 0
|
||||||
|
afr := 0
|
||||||
|
result := make([]byte, len(b))
|
||||||
|
copy(result, b)
|
||||||
|
per.bytes = append(per.bytes, result)
|
||||||
|
|
||||||
|
//从右往左找到第一个左边比右边小的数字
|
||||||
|
for bef = len(b) - 2; ; bef-- {
|
||||||
|
if bef < 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if b[bef] < b[bef+1] {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//知道q的位置之后
|
||||||
|
//从q开始向右边查找比位置q的数字大的第一个数字的位置
|
||||||
|
for afr = len(b) - 1; afr > 0; afr-- {
|
||||||
|
if b[afr] > b[bef] {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//交换两个数字
|
||||||
|
b[bef], b[afr] = b[afr], b[bef]
|
||||||
|
//把后面的数字进行转置成递增顺序
|
||||||
|
b = per.Reverse(b, bef+1, len(b)-1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (per *Permutation) Reverse(b []byte, start, end int) []byte {
|
||||||
|
for start <= end {
|
||||||
|
b[start], b[end] = b[end], b[start]
|
||||||
|
start++
|
||||||
|
end--
|
||||||
|
}
|
||||||
|
return b
|
||||||
|
}
|
||||||
@@ -0,0 +1,52 @@
|
|||||||
|
/*
|
||||||
|
* @Author : huangzj
|
||||||
|
* @Time : 2021/3/22 15:29
|
||||||
|
* @Description:
|
||||||
|
*/
|
||||||
|
|
||||||
|
package FullPermutation
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestDictionaryOrder(t *testing.T) {
|
||||||
|
p := NewPermutation()
|
||||||
|
|
||||||
|
p.DictionaryOrder([]byte("1234"))
|
||||||
|
fmt.Println()
|
||||||
|
for _, bs := range p.bytes {
|
||||||
|
fmt.Println(string(bs))
|
||||||
|
}
|
||||||
|
p.Reset()
|
||||||
|
|
||||||
|
p.DictionaryOrder([]byte("12345"))
|
||||||
|
fmt.Println()
|
||||||
|
for _, bs := range p.bytes {
|
||||||
|
fmt.Println(string(bs))
|
||||||
|
}
|
||||||
|
p.Reset()
|
||||||
|
|
||||||
|
p.DictionaryOrder([]byte("abcde"))
|
||||||
|
fmt.Println()
|
||||||
|
for _, bs := range p.bytes {
|
||||||
|
fmt.Println(string(bs))
|
||||||
|
}
|
||||||
|
p.Reset()
|
||||||
|
|
||||||
|
p.DictionaryOrder([]byte("abcdea"))
|
||||||
|
fmt.Println()
|
||||||
|
for _, bs := range p.bytes {
|
||||||
|
fmt.Println(string(bs))
|
||||||
|
}
|
||||||
|
p.Reset()
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPermutation_Reverse(t *testing.T) {
|
||||||
|
p := NewPermutation()
|
||||||
|
fmt.Println(p.Reverse([]byte{1, 2, 3, 4}, 0, 3))
|
||||||
|
fmt.Println(p.Reverse([]byte{1, 2, 3, 4, 5}, 0, 4))
|
||||||
|
fmt.Println(p.Reverse([]byte{1, 2, 3, 4, 5, 6}, 0, 5))
|
||||||
|
fmt.Println(p.Reverse([]byte{1, 2, 3, 4, 5, 6, 7}, 0, 6))
|
||||||
|
}
|
||||||
@@ -0,0 +1,71 @@
|
|||||||
|
/*
|
||||||
|
* @Author : huangzj
|
||||||
|
* @Time : 2021/3/23 17:06
|
||||||
|
* @Description:
|
||||||
|
*/
|
||||||
|
|
||||||
|
package FullPermutation
|
||||||
|
|
||||||
|
func DigitDecreases(b []int) [][]int {
|
||||||
|
result := make([][]int, 0)
|
||||||
|
bit := make([]int, len(b)-1)
|
||||||
|
sum := 1
|
||||||
|
//计算中的结果数,阶乘
|
||||||
|
for i := 1; i <= len(b); i++ {
|
||||||
|
sum = sum * i
|
||||||
|
}
|
||||||
|
for i := 0; i < sum; i++ {
|
||||||
|
result = append(result, getRangeBySpace1(b, bit))
|
||||||
|
bit = decreaseBit(bit)
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
//根据递增进制位,并且根据【数空格法】在原来的数组中求得全排列的一种可能实现
|
||||||
|
//origin 原始数组
|
||||||
|
//increaseBit 递增进制位,比原始数组长度小1,这里通过数组实现,更简单
|
||||||
|
func getRangeBySpace1(origin []int, increaseBit []int) []int {
|
||||||
|
permutation := make([]int, len(origin))
|
||||||
|
flag := make(map[int]bool, 0)
|
||||||
|
//排列数组从左往右,即从大到小
|
||||||
|
for i := 0; i < len(origin)-1; i++ {
|
||||||
|
p := increaseBit[i] //从右到左,对应数字应该填充的位置
|
||||||
|
j := len(origin) - 1 //该数字在本次排列的位置
|
||||||
|
for ; ; j-- {
|
||||||
|
//该位置未被填充
|
||||||
|
if !flag[j] {
|
||||||
|
p--
|
||||||
|
}
|
||||||
|
//找到对应位置需要推出循环
|
||||||
|
if p < 0 {
|
||||||
|
flag[j] = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
permutation[j] = origin[i]
|
||||||
|
}
|
||||||
|
for i := 0; i < len(origin); i++ {
|
||||||
|
if !flag[i] {
|
||||||
|
permutation[i] = origin[len(origin)-1]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return permutation
|
||||||
|
}
|
||||||
|
|
||||||
|
//递减进制位
|
||||||
|
//每次加一,计算新的数组结果
|
||||||
|
func decreaseBit(bit []int) []int {
|
||||||
|
|
||||||
|
//数组下标从小到大,进制位从大到小
|
||||||
|
for i := 0; i < len(bit); i++ {
|
||||||
|
if bit[i]+1 >= len(bit)+1-i {
|
||||||
|
bit[i] = (bit[i] + 1) % (len(bit) + 1 - i)
|
||||||
|
} else {
|
||||||
|
bit[i] += 1
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return bit
|
||||||
|
}
|
||||||
@@ -0,0 +1,59 @@
|
|||||||
|
/*
|
||||||
|
* @Author : huangzj
|
||||||
|
* @Time : 2021/3/23 19:53
|
||||||
|
* @Description:
|
||||||
|
*/
|
||||||
|
|
||||||
|
package FullPermutation
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestDecreaseBit(t *testing.T) {
|
||||||
|
|
||||||
|
bit := []int{0, 0}
|
||||||
|
for i := 0; i < 6; i++ {
|
||||||
|
fmt.Println(bit)
|
||||||
|
bit = decreaseBit(bit)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println()
|
||||||
|
bit = []int{0, 0, 0}
|
||||||
|
for i := 0; i < 24; i++ {
|
||||||
|
fmt.Println(bit)
|
||||||
|
bit = decreaseBit(bit)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println()
|
||||||
|
bit = []int{0, 0, 0, 0}
|
||||||
|
for i := 0; i < 120; i++ {
|
||||||
|
fmt.Print(bit)
|
||||||
|
bit = decreaseBit(bit)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
func TestGetRangeBySpace1(t *testing.T) {
|
||||||
|
fmt.Println(getRangeBySpace1([]int{1, 2, 3}, []int{0, 0}))
|
||||||
|
fmt.Println(getRangeBySpace1([]int{1, 2, 3}, []int{1, 0}))
|
||||||
|
fmt.Println(getRangeBySpace1([]int{1, 2, 3}, []int{2, 0}))
|
||||||
|
fmt.Println(getRangeBySpace1([]int{1, 2, 3}, []int{0, 1}))
|
||||||
|
fmt.Println(getRangeBySpace1([]int{1, 2, 3}, []int{1, 1}))
|
||||||
|
fmt.Println(getRangeBySpace1([]int{1, 2, 3}, []int{2, 1}))
|
||||||
|
|
||||||
|
fmt.Println(getRangeBySpace1([]int{1, 2, 3, 4, 5}, []int{0, 0, 0, 0}))
|
||||||
|
fmt.Println(getRangeBySpace1([]int{1, 2, 3, 4, 5}, []int{0, 0, 0, 1}))
|
||||||
|
fmt.Println(getRangeBySpace1([]int{1, 2, 3, 4, 5}, []int{4, 3, 2, 1}))
|
||||||
|
fmt.Println(getRangeBySpace1([]int{1, 2, 3, 4, 5}, []int{3, 0, 0, 0}))
|
||||||
|
fmt.Println(getRangeBySpace1([]int{1, 2, 3, 4, 5}, []int{1, 3, 2, 1}))
|
||||||
|
|
||||||
|
fmt.Println(getRangeBySpace1([]int{1, 2, 3, 4, 5, 6, 7}, []int{3, 4, 2, 2, 2, 1}))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestDigitDecrease(t *testing.T) {
|
||||||
|
fmt.Println(DigitDecreases([]int{1, 2, 3}))
|
||||||
|
fmt.Println(DigitDecreases([]int{20, 50, 30, 67}))
|
||||||
|
fmt.Println(DigitDecreases([]int{20, 50, 30, 99, 18213}))
|
||||||
|
fmt.Println(DigitDecreases([]int{20, 50, 30, 78321, 2321, 432}))
|
||||||
|
}
|
||||||
@@ -0,0 +1,71 @@
|
|||||||
|
/*
|
||||||
|
* @Author : huangzj
|
||||||
|
* @Time : 2021/3/23 17:05
|
||||||
|
* @Description:
|
||||||
|
*/
|
||||||
|
|
||||||
|
package FullPermutation
|
||||||
|
|
||||||
|
func DigitIncrease(b []int) [][]int {
|
||||||
|
result := make([][]int, 0)
|
||||||
|
bit := make([]int, len(b)-1)
|
||||||
|
sum := 1
|
||||||
|
//计算中的结果数,阶乘
|
||||||
|
for i := 1; i <= len(b); i++ {
|
||||||
|
sum = sum * i
|
||||||
|
}
|
||||||
|
for i := 0; i < sum; i++ {
|
||||||
|
result = append(result, getRangeBySpace(b, bit))
|
||||||
|
bit = increaseBit(bit)
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
//根据递增进制位,并且根据【数空格法】在原来的数组中求得全排列的一种可能实现
|
||||||
|
//origin 原始数组
|
||||||
|
//increaseBit 递增进制位,比原始数组长度小1,这里通过数组实现,更简单
|
||||||
|
func getRangeBySpace(origin []int, increaseBit []int) []int {
|
||||||
|
permutation := make([]int, len(origin))
|
||||||
|
flag := make(map[int]bool, 0)
|
||||||
|
//排列数组从左往右,即从大到小
|
||||||
|
for i := len(origin) - 1; i > 0; i-- {
|
||||||
|
p := increaseBit[i-1] //从右到左,对应数字应该填充的位置
|
||||||
|
j := len(origin) - 1 //该数字在本次排列的位置
|
||||||
|
//中介数计算从左到右,即从大到小
|
||||||
|
for ; ; j-- {
|
||||||
|
//该位置未被填充
|
||||||
|
if !flag[j] {
|
||||||
|
p--
|
||||||
|
}
|
||||||
|
//找到对应位置需要推出循环
|
||||||
|
if p < 0 {
|
||||||
|
flag[j] = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
permutation[j] = origin[i]
|
||||||
|
}
|
||||||
|
for i := 0; i < len(origin); i++ {
|
||||||
|
if !flag[i] {
|
||||||
|
permutation[i] = origin[0]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return permutation
|
||||||
|
}
|
||||||
|
|
||||||
|
//递增进制位
|
||||||
|
//根据递增进制位进行+1操作,返回递增的结果
|
||||||
|
func increaseBit(bit []int) []int {
|
||||||
|
//最开始是从二进制开始
|
||||||
|
for i, num := range bit {
|
||||||
|
if num+1 >= i+2 {
|
||||||
|
bit[i] = (num + 1) % (i + 2)
|
||||||
|
} else {
|
||||||
|
bit[i] = num + 1
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return bit
|
||||||
|
}
|
||||||
@@ -0,0 +1,57 @@
|
|||||||
|
/*
|
||||||
|
* @Author : huangzj
|
||||||
|
* @Time : 2021/3/23 19:54
|
||||||
|
* @Description:
|
||||||
|
*/
|
||||||
|
|
||||||
|
package FullPermutation
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestGetRangeBySpace(t *testing.T) {
|
||||||
|
fmt.Println(getRangeBySpace([]int{1, 2, 3}, []int{0, 0})) //123
|
||||||
|
fmt.Println(getRangeBySpace([]int{1, 2, 3}, []int{1, 0})) //
|
||||||
|
fmt.Println(getRangeBySpace([]int{1, 2, 3}, []int{0, 1})) //
|
||||||
|
fmt.Println(getRangeBySpace([]int{1, 2, 3}, []int{1, 1})) //
|
||||||
|
fmt.Println(getRangeBySpace([]int{1, 2, 3}, []int{0, 2})) //
|
||||||
|
fmt.Println(getRangeBySpace([]int{1, 2, 3}, []int{1, 2})) //321
|
||||||
|
|
||||||
|
//fmt.Println(getRangeBySpace([]int{1, 2, 3, 4, 5}, []int{0, 0, 0, 0})) //12345
|
||||||
|
//fmt.Println(getRangeBySpace([]int{1, 2, 3, 4, 5}, []int{0, 0, 0, 1})) //21354
|
||||||
|
fmt.Println(getRangeBySpace([]int{1, 2, 3, 4, 5}, []int{1, 2, 3, 4})) //54321
|
||||||
|
fmt.Println(getRangeBySpace([]int{1, 2, 3, 4, 5}, []int{0, 0, 0, 3})) //12534
|
||||||
|
fmt.Println(getRangeBySpace([]int{1, 2, 3, 4, 5}, []int{1, 2, 3, 1})) //43251
|
||||||
|
|
||||||
|
fmt.Println(getRangeBySpace([]int{1, 2, 3, 4, 5, 6, 7}, []int{1, 2, 2, 2, 4, 3})) //3647521
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestIncreaseBit(t *testing.T) {
|
||||||
|
bit := []int{0, 0}
|
||||||
|
for i := 0; i < 6; i++ {
|
||||||
|
fmt.Println(bit)
|
||||||
|
bit = increaseBit(bit)
|
||||||
|
}
|
||||||
|
fmt.Println()
|
||||||
|
|
||||||
|
bit = []int{0, 0, 0, 0}
|
||||||
|
for i := 0; i < 120; i++ {
|
||||||
|
bit = increaseBit(bit)
|
||||||
|
fmt.Println(bit)
|
||||||
|
}
|
||||||
|
|
||||||
|
bit = []int{0, 0, 0}
|
||||||
|
for i := 0; i < 24; i++ {
|
||||||
|
bit = increaseBit(bit)
|
||||||
|
fmt.Println(bit)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestDigitIncrease(t *testing.T) {
|
||||||
|
fmt.Println(DigitIncrease([]int{1, 2, 3}))
|
||||||
|
fmt.Println(DigitIncrease([]int{20, 50, 30, 67}))
|
||||||
|
fmt.Println(DigitIncrease([]int{20, 50, 30, 99, 18213}))
|
||||||
|
fmt.Println(DigitIncrease([]int{20, 50, 30, 78321, 2321, 432}))
|
||||||
|
}
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
/*
|
||||||
|
* @Author : huangzj
|
||||||
|
* @Time : 2021/3/22 11:09
|
||||||
|
* @Description:
|
||||||
|
*/
|
||||||
|
|
||||||
|
package FullPermutation
|
||||||
|
|
||||||
|
type Permutation struct {
|
||||||
|
bytes [][]byte
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewPermutation() *Permutation {
|
||||||
|
return &Permutation{
|
||||||
|
bytes: [][]byte{},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (per *Permutation) Recursion(b []byte, start int) {
|
||||||
|
//递归交换到最后一个位置结束
|
||||||
|
if start == len(b)-1 {
|
||||||
|
bCopy := make([]byte, len(b))
|
||||||
|
copy(bCopy, b)
|
||||||
|
per.bytes = append(per.bytes, bCopy)
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := start; i < len(b); i++ {
|
||||||
|
//交换固定位置
|
||||||
|
b[i], b[start] = b[start], b[i]
|
||||||
|
//固定某一个数字位置,递归后面的其他数字
|
||||||
|
per.Recursion(b, start+1)
|
||||||
|
//还原固定位置,进行下一次操作
|
||||||
|
b[i], b[start] = b[start], b[i]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (per *Permutation) Reset() {
|
||||||
|
per.bytes = [][]byte{}
|
||||||
|
}
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
/*
|
||||||
|
* @Author : huangzj
|
||||||
|
* @Time : 2021/3/22 11:22
|
||||||
|
* @Description:
|
||||||
|
*/
|
||||||
|
|
||||||
|
package FullPermutation
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestRecursion(t *testing.T) {
|
||||||
|
p := NewPermutation()
|
||||||
|
|
||||||
|
p.Recursion([]byte("123"), 0)
|
||||||
|
fmt.Println()
|
||||||
|
for _, bs := range p.bytes {
|
||||||
|
fmt.Println(string(bs))
|
||||||
|
}
|
||||||
|
p.Reset()
|
||||||
|
|
||||||
|
p.Recursion([]byte("12345"), 0)
|
||||||
|
fmt.Println()
|
||||||
|
for _, bs := range p.bytes {
|
||||||
|
fmt.Println(string(bs))
|
||||||
|
}
|
||||||
|
p.Reset()
|
||||||
|
|
||||||
|
p.Recursion([]byte("abcde"), 0)
|
||||||
|
fmt.Println()
|
||||||
|
for _, bs := range p.bytes {
|
||||||
|
fmt.Println(string(bs))
|
||||||
|
}
|
||||||
|
p.Reset()
|
||||||
|
|
||||||
|
p.Recursion([]byte("abcdea"), 0)
|
||||||
|
fmt.Println()
|
||||||
|
for _, bs := range p.bytes {
|
||||||
|
fmt.Println(string(bs))
|
||||||
|
}
|
||||||
|
p.Reset()
|
||||||
|
|
||||||
|
}
|
||||||
@@ -17,6 +17,14 @@ func QuickSort(list []int, start, end int) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func QuickSortByte(list []byte, start, end int) {
|
||||||
|
if start < end {
|
||||||
|
position := hoarePartition1(list, start, end)
|
||||||
|
QuickSortByte(list, start, position) //注意这边结束的下表是position,而不是position + 1
|
||||||
|
QuickSortByte(list, position+1, end)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//通过lomuto划分来实现快速排序
|
//通过lomuto划分来实现快速排序
|
||||||
func QuickSort1(list []int, start, end int) {
|
func QuickSort1(list []int, start, end int) {
|
||||||
if start < end {
|
if start < end {
|
||||||
@@ -26,6 +34,25 @@ func QuickSort1(list []int, start, end int) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func hoarePartition1(list []byte, start int, end int) int {
|
||||||
|
value := list[start] //比较的元素
|
||||||
|
s := start
|
||||||
|
e := end
|
||||||
|
for s < e {
|
||||||
|
//找到数组终止前,比目标数(value)大的数字
|
||||||
|
for ; s < end && list[s] < value; s++ {
|
||||||
|
}
|
||||||
|
//找到数组结束前,比目标数(value)小的数字
|
||||||
|
for ; e > start && list[e] >= value; e-- {
|
||||||
|
}
|
||||||
|
if s < e {
|
||||||
|
list[s], list[e] = list[e], list[s]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
list[start], list[e] = list[e], list[start]
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
|
||||||
func hoarePartition(list []int, start int, end int) int {
|
func hoarePartition(list []int, start int, end int) int {
|
||||||
value := list[start] //比较的元素
|
value := list[start] //比较的元素
|
||||||
s := start
|
s := start
|
||||||
|
|||||||
Reference in New Issue
Block a user