赛码2. 翻转数组Golang版
1. 问题描述
给定一个长度为n的整数数组a,元素均不相同,问数组是否存在这样一个片段,只将该片段翻转就可以使整个数组升序排列。其中数组片段[l,r]表示序列a[l], a[l+1], …, a[r]。原始数组为
a[1], a[2], …, a[l-2], a[l-1], a[l], a[l+1], …, a[r-1], a[r], a[r+1], a[r+2], …, a[n-1], a[n],
将片段[l,r]反序后的数组是
a[1], a[2], …, a[l-2], a[l-1], a[r], a[r-1], …, a[l+1], a[l], a[r+1], a[r+2], …, a[n-1], a[n]。
2. 思路
- 把数组中的元素拷贝到一个新数组
copynums
中,并对copynums
排序 - 从左到右遍历数组,找到
nums
和copynums
中第一个不相等的位置l
- 从右到左遍历数组,找到
nums
和copynums
中第一个不相等的位置r
- 比较区间
[l,r]
内,nums[l]
是否等于nums[r]
,循环l++,r--
3. 代码
package main
import (
"bufio"
"fmt"
"os"
"sort"
"strconv"
"strings"
)
func main() {
sc := bufio.NewScanner(os.Stdin)
// bs := make([]byte, 2000 * 1024)
// sc.Buffer(bs, len(bs))
sc.Scan()
N, _ := strconv.Atoi(sc.Text())
nums := make([]int, N)
sc.Scan()
l := strings.Split(sc.Text()," ")
for i, s := range l {
v,_ := strconv.Atoi(s)
nums[i] = v
}
//fmt.Println(nums)
doReverse(N, nums)
}
func doReverse(n int, nums []int) {
cpnums := make([]int, n)
copy(cpnums, nums)
sort.Ints(cpnums)
var l, r int
for i := 0; i < n; i++ {
if cpnums[i] != nums[i]{
l = i
break
}
}
for j := n-1; j >= 0; j-- {
if cpnums[j] != nums[j] {
r = j
break
}
}
flag := true
right := r
for l <= right && r >= 0 {
if cpnums[l] != nums[r] {
flag = false
break
}
l++
r--
}
if flag == true {
fmt.Println("yes")
} else {
fmt.Println("no")
}
}