-
Notifications
You must be signed in to change notification settings - Fork 51
/
Copy pathlongest_palindrome.go
71 lines (59 loc) · 2.17 KB
/
longest_palindrome.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
package main
import (
"bufio"
"fmt"
"os"
)
func main() {
scanner := bufio.NewScanner(os.Stdin)
const maxCapacity = 8 * 100000
buffer := make([]byte, maxCapacity)
scanner.Buffer(buffer, maxCapacity)
var line string
// читаем входную строку
scanner.Scan()
line = scanner.Text()
// находим самый длинный палиндром (лексикографически минимальный),
// который можно получить из строки путём удаления и перестановки символов
// т.к. допустимы перестановки, то порядок символов не влияет на решение
// посчитаем частоту каждого символа во входной строке
counter := make(map[rune]int)
for _, symbol := range line {
count, contains := counter[symbol]
if !contains {
counter[symbol] = 1
} else {
counter[symbol] = count + 1
}
}
// все символы, имеющие чётную частоту (2n), будут частью ответа, т.к.
// мы можем поместить n символов в начало палиндрома, а остальные n
// символов - в конец. Для символов, имеющих нечётную частоту, мы заполним
// середину палиндрома одним из таких символов, а оставшиеся 2*n символов
// разделим пополам и добавим в начало и в конец
var begin, mid, end []rune
for i := 97; i <= 122; i++ {
r := rune(i)
count, contains := counter[r]
if !contains || count == 0 {
continue
}
// нечётная частота символа
if count%2 == 1 && len(mid) == 0 {
mid = []rune{r}
counter[r] = count - 1
i--
} else {
// чётная частота символа
for i := 0; i < count/2; i++ {
begin = append(begin, r)
}
}
}
// end - это реверс от begin
for i := len(begin) - 1; i >= 0; i-- {
end = append(end, begin[i])
}
palindrome := string(begin) + string(mid) + string(end)
fmt.Print(palindrome)
}