本篇博客是用Go语言编写的详尽简洁代码,这里没有写算法思路,若要看具体思路,请移步力扣官网查看相关高赞题解。本篇博客的特点是代码简洁明了,包含多种写法,适合读者后期复盘巩固,加深理解。这一百题是面试高频题,建议读者认真阅读,背诵记忆。欢迎点赞+收藏+关注~~
func dfs(p, q *TreeNode) bool {
if p == nil && q == nil {
return true
}
if p == nil || q == nil || p.Val != q.Val {
return false
}
return dfs(p.Left, q.Right) && dfs(p.Right, q.Left)
}
func isSymmetric(root *TreeNode) bool {
if root == nil {
return true
}
return dfs(root.Left, root.Right)
}
var ans [][]int
func dfs(root *TreeNode, dep int) {
if root == nil {
return
}
if len(ans) == dep {
ans = append(ans, []int{})
}
ans[dep] = append(ans[dep], root.Val)
if root.Left != nil {
dfs(root.Left, dep + 1)
}
if root.Right != nil {
dfs(root.Right, dep + 1)
}
}
func levelOrder(root *TreeNode) [][]int {
if root == nil {
return [][]int{}
}
ans = make([][]int, 0)
dfs(root, 0)
return ans
}
func levelOrder(root *TreeNode) [][]int {
if root == nil {
return [][]int{}
}
ans := [][]int{}
q := [] *TreeNode{}
q = append(q, root)
for len(q) > 0 {
s := len(q)
tmp := []int{}
for i := 1; i <= s; i ++ {
t := q[0]
q = q[1:]
tmp = append(tmp, t.Val)
if t.Left != nil {
q = append(q, t.Left)
}
if t.Right != nil {
q = append(q, t.Right)
}
}
ans = append(ans, tmp)
}
return ans
}
var ans [][]int
func dfs(root *TreeNode, dep int) {
if root == nil {
return
}
if len(ans) == dep {
ans = append(ans, []int{})
}
if dep & 1 != 0 {
ans[dep] = append(append([]int{}, root.Val), ans[dep]...)
} else {
ans[dep] = append(ans[dep], root.Val)
}
if root.Left != nil {
dfs(root.Left, dep + 1)
}
if root.Right != nil {
dfs(root.Right, dep + 1)
}
}
func zigzagLevelOrder(root *TreeNode) [][]int {
if root == nil {
return [][]int{}
}
ans = make([][]int, 0)
dfs(root, 0)
return ans
}
func zigzagLevelOrder(root *TreeNode) [][]int {
if root == nil {
return [][]int{}
}
ans := [][]int{}
q := []*TreeNode{}
q = append(q, root)
k := 0
for len(q) > 0 {
s := len(q)
tmp := []int{}
for i := 1; i <= s; i ++ {
t := q[0]
q = q[1:]
tmp = append(tmp, t.Val)
if t.Left != nil {
q = append(q, t.Left)
}
if t.Right != nil {
q = append(q, t.Right)
}
}
if k & 1 != 0 {
i, j := 0, len(tmp) - 1
for i < j {
tmp[i], tmp[j] = tmp[j], tmp[i]
i ++
j --
}
}
ans = append(ans, tmp)
k ^= 1
}
return ans
}
func maxDepth(root *TreeNode) int {
if root == nil {
return 0
}
return max(maxDepth(root.Left), maxDepth(root.Right)) + 1
}
func max(x, y int) int {
if x > y {
return x
}
return y
}
func maxDepth(root *TreeNode) int {
if root == nil {
return 0
}
q := []*TreeNode{}
q = append(q, root)
dep := 0
for len(q) > 0 {
s := len(q)
for i := 1; i <= s; i ++ {
t := q[0]
q = q[1:]
if t.Left != nil {
q = append(q, t.Left)
}
if t.Right != nil {
q = append(q, t.Right)
}
}
dep ++
}
return dep
}
var pos map[int]int
func build(preorder, inorder []int, pl, pr, il, ir int) *TreeNode {
if pl > pr {
return nil
}
root := &TreeNode{Val : preorder[pl]}
k := pos[root.Val]
if il < k {
root.Left = build(preorder, inorder, pl + 1, pl + k - il, il, k - 1)
}
if k < ir {
root.Right = build(preorder, inorder, pl + k - il + 1, pr, k + 1, ir)
}
return root
}
func buildTree(preorder []int, inorder []int) *TreeNode {
pos = map[int]int{}
n := len(preorder)
for i := 0; i < n; i ++ {
pos[inorder[i]] = i
}
return build(preorder, inorder, 0, n - 1, 0, n - 1)
}
var pos map[int]int
func build(inorder, postorder []int, il, ir, pl, pr int) *TreeNode {
if il > ir {
return nil
}
root := &TreeNode{Val : postorder[pr]}
k := pos[root.Val]
if il < k {
root.Left = build(inorder, postorder, il, k - 1, pl, pl + k - il - 1)
}
if k < ir {
root.Right = build(inorder, postorder, k + 1, ir, pl + k - il, pr - 1)
}
return root
}
func buildTree(inorder []int, postorder []int) *TreeNode {
pos = map[int]int{}
n := len(inorder)
for i := 0; i < n; i ++ {
pos[inorder[i]] = i
}
return build(inorder, postorder, 0, n - 1, 0, n - 1)
}
var ans [][]int
func dfs(root *TreeNode, dep int) {
if root == nil {
return
}
if dep == len(ans) {
ans = append(ans, []int{})
}
ans[dep] = append(ans[dep], root.Val)
if root.Left != nil {
dfs(root.Left, dep + 1)
}
if root.Right != nil {
dfs(root.Right, dep + 1)
}
}
func levelOrderBottom(root *TreeNode) [][]int {
ans = [][]int{}
if root == nil {
return [][]int{}
}
dfs(root, 0)
l, r := 0, len(ans) - 1
for l < r {
ans[l], ans[r] = ans[r], ans[l]
l ++
r --
}
return ans
}
func levelOrderBottom(root *TreeNode) [][]int {
if root == nil {
return [][]int{}
}
ans := [][]int{}
q := []*TreeNode{}
q = append(q, root)
for len(q) > 0 {
s := len(q)
tmp := []int{}
for i := 0; i < s; i ++ {
t := q[0]
q = q[1 :]
tmp = append(tmp, t.Val)
if t.Left != nil {
q = append(q, t.Left)
}
if t.Right != nil {
q = append(q, t.Right)
}
}
ans = append(ans, tmp)
}
l, r := 0, len(ans) - 1
for l < r {
ans[l], ans[r] = ans[r], ans[l]
l ++
r --
}
return ans
}
var a []int
func build(l, r int) *TreeNode {
if l > r {
return nil
}
mid := (l + r) >> 1
root := &TreeNode{Val : a[mid]}
root.Left = build(l, mid - 1)
root.Right = build(mid + 1, r)
return root
}
func sortedArrayToBST(nums []int) *TreeNode {
a = nums
return build(0, len(a) - 1)
}
func sortedListToBST(head *ListNode) *TreeNode {
if head == nil {
return nil
}
var slow, fast, preSlow *ListNode
slow, fast, preSlow = head, head, nil
for fast != nil && fast.Next != nil {
preSlow = slow
slow = slow.Next
fast = fast.Next.Next
}
root := &TreeNode{Val: slow.Val} // slow是中点 将slow作为BST的根节点
if preSlow != nil {
preSlow.Next = nil // 建立左子树前,要把 左边链表尾preSlow 指向空
root.Left = sortedListToBST(head) // head 是 左子树根结点
}
root.Right = sortedListToBST(slow.Next) // slow->next 是 右子树根结点
return root
}
var h *ListNode
func build(l, r int) *TreeNode {
if l > r {
return nil
}
mid := (l + r) >> 1
lc := build(l, mid - 1)
root := &TreeNode{Val: h.Val}
h = h.Next
root.Left = lc
root.Right = build(mid + 1, r)
return root
}
func sortedListToBST(head *ListNode) *TreeNode {
h = head
n := 0
for p := head; p != nil; p = p.Next {
n ++
}
return build(0, n - 1)
}
func getHeight(root *TreeNode) int {
if root == nil {
return 0
}
lh := getHeight(root.Left)
if lh == - 1 {
return -1
}
rh := getHeight(root.Right)
if rh == -1 {
return -1
}
if abs(rh - lh) > 1 {
return -1
}
return max(lh, rh) + 1
}
func isBalanced(root *TreeNode) bool {
if root == nil {
return true
}
if getHeight(root) == -1 {
return false
}
return true
}
func abs(x int) int {
if x < 0 {
return -x
}
return x
}
func max(x, y int) int {
if x > y {
return x
}
return y
}
func minDepth(root *TreeNode) int {
if root == nil {
return 0
}
if root.Left == nil {
return 1 + minDepth(root.Right)
}
if root.Right == nil {
return 1 + minDepth(root.Left)
}
return min(minDepth(root.Left), minDepth(root.Right)) + 1
}
func min(x, y int) int {
if x < y {
return x
}
return y
}
func hasPathSum(root *TreeNode, sum int) bool {
if root == nil {
return false
}
if root.Left == nil && root.Right == nil {
return sum == root.Val
}
return hasPathSum(root.Left, sum - root.Val) || hasPathSum(root.Right, sum - root.Val)
}
var ans [][]int
func dfs(root *TreeNode, sum int, path []int) {
if root == nil {
return
}
path = append(path, root.Val)
sum -= root.Val
if root.Left == nil && root.Right == nil && sum == 0{
tmp := make([]int, len(path))
copy(tmp, path)
ans = append(ans, tmp)
return
}
if root.Left != nil {
dfs(root.Left, sum, path)
}
if root.Right != nil {
dfs(root.Right, sum, path)
}
}
func pathSum(root *TreeNode, targetSum int) [][]int {
if root == nil {
return [][]int{}
}
ans = [][]int{}
path := []int{}
dfs(root, targetSum, path)
return ans
}
func flatten(root *TreeNode) {
for root != nil {
p := root.Left
if p != nil {
for p.Right != nil {
p = p.Right
}
p.Right = root.Right
root.Right = root.Left
root.Left = nil
}
root = root.Right
}
}
func numDistinct(s string, t string) int {
n, m := len(s), len(t)
if n < m {
return 0
}
s, t = " " + s, " " + t
f := make([][]int, n + 1)
for i := 0; i <= n; i ++ {
f[i] = make([]int, m + 1)
f[i][0] = 1
}
for i := 1; i <= n; i ++ {
for j := 1; j <= m; j ++ {
f[i][j] = f[i - 1][j]
if s[i] == t[j] {
f[i][j] += f[i - 1][j - 1]
}
}
}
return f[n][m]
}
func connect(root *Node) *Node {
if root == nil {
return nil
}
rt := root
for root.Left != nil {
for p := root; p != nil; p = p.Next {
p.Left.Next = p.Right
if p.Next != nil {
p.Right.Next = p.Next.Left
}
}
root = root.Left
}
return rt
}
func connect(root *Node) *Node {
if root == nil {
return nil
}
rt := root
for root != nil {
dummy := &Node{}
tail := dummy
for p := root; p != nil; p = p.Next {
if p.Left != nil {
tail.Next = p.Left
tail = tail.Next
}
if p.Right != nil {
tail.Next = p.Right
tail = tail.Next
}
}
root = dummy.Next
}
return rt
}
func generate(n int) [][]int {
f := make([][]int, n)
for i := 0; i < n; i ++ {
f[i] = make([]int, i + 1)
f[i][0], f[i][i] = 1, 1
for j := 1; j < i; j ++ {
f[i][j] = f[i - 1][j - 1] + f[i - 1][j]
}
}
return f
}
func getRow(n int) []int {
f := make([]int, n + 1)
for i := 0; i <= n; i ++ {
f[i] = 1
}
for i := 0; i <= n; i ++ {
for j := i - 1; j > 0; j -- {
f[j] += f[j - 1]
}
}
return f
}
func minimumTotal(w [][]int) int {
n := len(w)
f := make([]int, n + 1)
for i := n - 1; i >= 0; i -- {
for j := 0; j <= i; j ++ {
f[j] = min(f[j], f[j + 1]) + w[i][j]
}
}
return f[0]
}
func minimumTotal(w [][]int) int {
n := len(w)
for i := n - 2; i >= 0; i -- {
for j := i; j >= 0; j -- {
w[i][j] += min(w[i + 1][j], w[i + 1][j + 1])
}
}
return w[0][0]
}
func maxProfit(prices []int) int {
ans, low := 0, math.MaxInt32
for _, x := range prices {
low = min(low, x)
ans = max(ans, x - low)
}
return ans
}
func maxProfit(prices []int) int {
n := len(prices)
f := make([][]int, n)
for i := 0; i < n; i ++ {
f[i] = make([]int, 2)
}
f[0][0], f[0][1] = 0, -prices[0]
for i := 1; i < n; i ++ {
f[i][0] = max(f[i - 1][0], f[i - 1][1] + prices[i])
f[i][1] = max(f[i - 1][1], -prices[i])
}
return f[n - 1][0]
}
func maxProfit(prices []int) int {
n := len(prices)
f := make([][]int, n)
for i := 0; i < n; i ++ {
f[i] = make([]int, 2)
}
f[0][0], f[0][1] = 0, -prices[0]
for i := 1; i < n; i ++ {
f[i][0] = max(f[i - 1][0], f[i - 1][1] + prices[i])
f[i][1] = max(f[i - 1][1], f[i - 1][0] - prices[i])
}
return f[n - 1][0]
}
func maxProfit(prices []int) int {
n := len(prices)
f := make([][]int, 3)
for i := 0; i < 3; i ++ {
f[i] = make([]int, 2)
}
prices = append([]int{-1}, prices...)
for j := 0; j <= 2; j ++ {
f[j][1] = math.MinInt32
}
for i := 1; i <= n; i ++ {
for j := 1; j <= 2; j ++ {
f[j][0] = max(f[j][0], f[j][1] + prices[i])
f[j][1] = max(f[j][1], f[j - 1][0] - prices[i])
}
}
return f[2][0]
}
var ans int
func dfs(root *TreeNode) int {
if root == nil {
return 0
}
l := max(0, dfs(root.Left))
r := max(0, dfs(root.Right))
ans = max(ans, l + root.Val + r)
return root.Val + max(l, r)
}
func maxPathSum(root *TreeNode) int {
ans = math.MinInt32
dfs(root)
return ans
}
func check(c byte) bool {
return c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z' || c >= '0' && c <= '9'
}
func isPalindrome(s string) bool {
for i, j := 0, len(s) - 1; i < j; i, j = i + 1, j - 1 {
for i < j && !check(s[i]) {
i ++
}
for i < j && !check(s[j]) {
j --
}
if i < j && strings.ToLower(string(s[i])) != strings.ToLower(string(s[j])) {
return false
}
}
return true
}
class Solution {
public:
unordered_map dist;
unordered_set S;
vector> ans;
vector path;
queue q;
string beginWord, endWord;
void bfs() {
q.push(beginWord);
dist[beginWord] = 0;
while (!q.empty()) {
string t = q.front(); q.pop();
for (int i = 0; i < t.size(); ++ i) {
string x = t;
for (char c = 'a'; c <= 'z'; ++ c) {
x[i] = c;
if (S.count(x) && !dist.count(x)) {
dist[x] = dist[t] + 1;
if (x == endWord) break;
q.push(x);
}
}
}
}
}
void dfs(string t) {
if (t == beginWord) {
ans.push_back({path.rbegin(), path.rend()});
return ;
}
for (int i = 0; i < t.size(); ++ i) {
string x = t;
for (char c = 'a'; c <= 'z'; ++ c) {
x[i] = c;
if (dist.count(x) && dist[x] + 1 == dist[t]) {
path.push_back(x);
dfs(x);
path.pop_back();
}
}
}
}
vector> findLadders(string beginWord, string endWord, vector& wordList) {
this->beginWord = beginWord, this->endWord = endWord;
for (auto& x : wordList) S.insert(x);
if (!S.count(endWord)) return {};
bfs();
if (!dist.count(endWord)) return {};
path.push_back(endWord);
dfs(endWord);
return ans;
}
};
class Solution {
public:
int ladderLength(string beginWord, string endWord, vector& wordList) {
queue q;
unordered_map dist;
unordered_set S(wordList.begin(), wordList.end());
if (!S.count(endWord)) return 0;
dist[beginWord] = 1;
q.push(beginWord);
while (!q.empty()) {
string t = q.front(); q.pop();
for (int i = 0; i < t.size(); ++ i) {
string x = t;
for (char c = 'a'; c <= 'z'; ++ c) {
x[i] = c;
if (S.count(x) && !dist.count(x)) {
dist[x] = dist[t] + 1;
if (x == endWord) return dist[x];
q.push(x);
}
}
}
}
return 0;
}
};
func longestConsecutive(nums []int) int {
S := map[int]bool{}
for _, x := range nums {
S[x] = true
}
ans := 0
for _, x := range nums {
if S[x] && !S[x - 1] {
delete(S, x)
y := x
for S[y + 1] {
y ++
delete(S, y)
}
ans = max(ans, y - x + 1)
}
}
return ans
}
var f, cnt map[int]int
func find(x int)int {
if x != f[x] {
f[x] = find(f[x])
}
return f[x]
}
func Union(x, y int) {
a, b := find(x), find(y)
if a != b {
f[a] = b
cnt[b] += cnt[a]
}
}
func longestConsecutive(nums []int) int {
f, cnt = map[int]int{}, map[int]int{}
for _, x := range nums {
if _, ok := f[x]; ok {
continue
} else {
f[x], cnt[x] = x, 1
}
if _, ok := f[x - 1]; ok {
Union(x, x - 1)
}
if _, ok := f[x + 1]; ok {
Union(x, x + 1)
}
}
ans := 0
for _, v := range cnt {
ans = max(ans, v)
}
return ans
}
var ans int
func dfs(root *TreeNode, x int) {
if root == nil {
return
}
x = x * 10 + root.Val
if root.Left == nil && root.Right == nil {
ans += x
return
}
if root.Left != nil {
dfs(root.Left, x)
}
if root.Right != nil {
dfs(root.Right, x)
}
}
func sumNumbers(root *TreeNode) int {
ans = 0
if root == nil {
return 0
}
dfs(root, 0)
return ans
}
var (
dx, dy []int
n, m int
)
func dfs(g [][]byte, x, y int) {
g[x][y] = '#'
for i := 0; i < 4; i ++ {
a, b := x + dx[i], y + dy[i]
if a < 0 || a >= n || b < 0 || b >= m || g[a][b] == '#' {
continue
}
if g[a][b] == 'O' {
dfs(g, a, b)
}
}
}
func solve(g [][]byte) {
dx, dy = []int{-1, 0, 1, 0}, []int{0, 1, 0, -1}
n, m = len(g), len(g[0])
if n == 0 {
return
}
for i := 0; i < n; i ++ {
if g[i][0] == 'O' {
dfs(g, i, 0)
}
if g[i][m - 1] == 'O' {
dfs(g, i, m - 1)
}
}
for j := 0; j < m; j ++ {
if g[0][j] == 'O' {
dfs(g, 0, j)
}
if g[n - 1][j] == 'O' {
dfs(g, n - 1, j)
}
}
for i := 0; i < n; i ++ {
for j := 0; j < m; j ++ {
if g[i][j] == '#' {
g[i][j] = 'O'
} else {
g[i][j] = 'X'
}
}
}
}
var p []int
func find(x int) int {
if x != p[x] {
p[x] = find(p[x])
}
return p[x]
}
func solve(g [][]byte) {
p = []int{}
dx, dy := []int{-1, 0, 1, 0}, []int{0, 1, 0, -1}
n, m := len(g), len(g[0])
for i := 0; i <= n * m; i ++ {
p = append(p, i)
}
for i := 0; i < n; i ++ {
for j := 0; j < m; j ++ {
if g[i][j] == 'O' {
if i == 0 || i == n - 1 || j == 0 || j == m - 1 {
p[find(i * m + j)] = find(n * m)
} else {
for k := 0; k < 4; k ++ {
a, b := i + dx[k], j + dy[k]
if a >= 0 && a < n && b >= 0 && b < m && g[a][b] == 'O' {
p[find(i * m + j)] = find(a * m + b)
}
}
}
}
}
}
for i := 0; i < n; i ++ {
for j := 0; j < m; j ++ {
if find(i * m + j) == find(n * m) {
continue
} else {
g[i][j] = 'X'
}
}
}
}
var (
n int
path []string
f [][]bool
ans [][]string
)
func dfs(s string, i int) {
if i == n {
ans = append(ans, append([]string{}, path...))
return
}
for j := i; j < n; j ++ {
if f[i][j] {
path = append(path, s[i : j + 1])
dfs(s, j + 1)
path = path[ : len(path) - 1]
}
}
}
func partition(s string) [][]string {
n = len(s)
path = []string{}
f = make([][]bool, n)
ans = [][]string{}
for i := 0; i < n; i ++ {
f[i] = make([]bool, n)
for j := 0; j < n; j ++ {
f[i][j] = true
}
}
for i := n - 1; i >= 0; i -- {
for j := i + 1; j < n; j ++ {
f[i][j] = f[i + 1][j - 1] && (s[i] == s[j])
}
}
dfs(s, 0)
return ans
}
var (
f [][]bool
ans [][]string
path []string
s string
n int
)
func dfs(i int) {
if i == len(s) {
tmp := make([]string, len(path))
copy(tmp, path)
ans = append(ans, tmp)
return
}
for j := i; j < len(s); j ++ {
if f[i][j] {
path = append(path, s[i : j + 1])
dfs(j + 1)
path = path[ : len(path) - 1]
}
}
}
func partition(_s string) [][]string {
s = _s
n = len(s)
path, ans = []string{}, [][]string{}
f = make([][]bool, n)
for i := 0; i < n; i ++ {
f[i] = make([]bool, n)
for j := 0; j < n; j ++ {
f[i][j] = false
}
}
for i := 0; i < n; i ++ {
f[i][i] = true
}
for len := 2; len <= n; len ++ {
for i := 0; i + len - 1 < n; i ++ {
j := i + len - 1
if len == 2 {
f[i][j] = s[i] == s[j]
} else {
f[i][j] = (s[i] == s[j]) && f[i + 1][j - 1]
}
}
}
dfs(0)
return ans
}
var (
f [][]bool
ans [][]string
path []string
s string
)
func initialize() {
n := len(s)
f = make([][]bool, n)
for i := 0; i < n; i ++ {
f[i] = make([]bool, n)
}
for j := 0; j < n; j ++ {
for i := 0; i <= j; i ++ {
if i == j {
f[i][j] = true
} else if s[i] == s[j] {
if i + 1 == j || f[i + 1][j - 1] {
f[i][j] = true
}
}
}
}
}
func dfs(u int) {
if u == len(s) {
tmp := make([]string, len(path))
copy(tmp, path)
ans = append(ans, tmp)
return
}
for i := u; i < len(s); i ++ {
if f[u][i] {
path = append(path, s[u : i + 1])
dfs(i + 1)
path = path[ : len(path) - 1]
}
}
}
func partition(_s string) [][]string {
s = _s
path, ans = []string{}, [][]string{}
initialize()
dfs(0)
return ans
}
func minCut(s string) int {
n := len(s)
s = " " + s
g := make([][]bool, n + 1)
for i := range g {
g[i] = make([]bool, n + 1)
}
for j := 1; j <= n; j ++ {
for i := 1; i <= j; i ++ {
if i == j {
g[i][j] = true
} else if s[i] == s[j] {
g[i][j] = i + 1 == j || g[i + 1][j - 1]
}
}
}
f := make([]int, n + 1)
for i := range f {
f[i] = math.MaxInt32
}
f[0] = 0
for i := 1; i <= n; i ++ {
for j := 1; j <= i; j ++ {
if g[j][i] {
f[i] = min(f[i], f[j - 1] + 1)
}
}
}
return f[n] - 1
}
func minCut(s string) int {
n := len(s)
s = " " + s
g := make([][]bool, n + 1)
for i := 0; i < n + 1; i ++ {
g[i] = make([]bool, n + 1)
for j := 0; j < n + 1; j ++ {
g[i][j] = true
}
}
for i := n; i >= 0; i -- {
for j := i + 1; j < n + 1; j ++ {
g[i][j] = g[i + 1][j - 1] && (s[i] == s[j])
}
}
f := make([]int, n + 1)
for i := 0; i < n + 1; i ++ {
f[i] = math.MaxInt32
}
f[0] = 0
for i := 1; i <= n; i ++ {
for j := 1; j <= i; j ++ {
if g[j][i] {
f[i] = min(f[i], f[j - 1] + 1)
}
}
}
return f[n] - 1
}
func minCut(s string) int {
n := len(s)
s = " " + s
g := make([][]bool, n + 1)
for i := range g {
g[i] = make([]bool, n + 1)
}
for i := 1; i <= n; i ++ {
g[i][i] = true
}
for len := 2; len <= n; len ++ {
for i := 1; i + len - 1 <= n; i ++ {
j := i + len - 1
if len == 2 {
g[i][j] = s[i] == s[j]
} else {
g[i][j] = (s[i] == s[j]) && g[i + 1][j - 1]
}
}
}
f := make([]int, n + 1)
for i := range f {
f[i] = math.MaxInt32
}
f[0] = 0
for i := 1; i <= n; i ++ {
for j := 1; j <= i; j ++ {
if g[j][i] {
f[i] = min(f[i], f[j - 1] + 1)
}
}
}
return f[n] - 1
}
var mp map[*Node]*Node
func dfs(node *Node) {
mp[node] = &Node{Val: node.Val}
for i := 0; i < len(node.Neighbors); i ++ {
ver := node.Neighbors[i]
if _, ok := mp[ver]; !ok {
dfs(ver)
}
}
}
func cloneGraph(node *Node) *Node {
if node == nil {
return nil
}
mp = map[*Node]*Node{}
dfs(node)
for s, d := range mp {
for i := 0; i < len(s.Neighbors); i ++ {
ver := s.Neighbors[i]
d.Neighbors = append(d.Neighbors, mp[ver])
}
}
return mp[node]
}
func canCompleteCircuit(gas []int, cost []int) int {
i, j, n := 0, 0, len(gas)
for i < n {
s := 0
for j < n {
k := (i + j) % n
s += gas[k] - cost[k]
if s < 0 {
break
}
j ++
}
if j == n {
return i
}
i, j = i + j + 1, 0
}
return -1
}
func canCompleteCircuit(gas []int, cost []int) int {
n := len(gas)
s := make([]int, 2 * n + 1)
for i := 1; i <= n; i ++ {
s[i] = gas[i - 1] - cost[i - 1]
s[i + n] = s[i]
}
for i := 1; i <= 2 * n; i ++ {
s[i] += s[i - 1]
}
q := make([]int, 2 * n + 1)
hh, tt := 0, -1
for i := 2 * n; i > 0; i -- {
if hh <= tt && q[hh] > i + n {
hh ++
}
for hh <= tt && s[q[tt]] >= s[i] {
tt --
}
if i <= n && s[q[hh]] - s[i] >= 0 {
return i % n
}
tt ++
q[tt] = i
}
return -1
}
var (
n int
w, f []int
)
func dfs(x int) int {
if f[x] != -1 {
return f[x]
}
f[x] = 1
if x > 0 && w[x - 1] < w[x] {
f[x] = max(f[x], dfs(x - 1) + 1)
}
if x + 1 < n && w[x + 1] < w[x] {
f[x] = max(f[x], dfs(x + 1) + 1)
}
return f[x]
}
func candy(ratings []int) int {
w = ratings
n = len(w)
f = make([]int, n)
for i := 0; i < n; i ++ {
f[i] = -1
}
ans := 0
for i := 0; i < n; i ++ {
ans += dfs(i)
}
return ans
}
func candy(w []int) int {
n := len(w)
l, r := make([]int, n), make([]int, n)
for i := 0; i < n; i ++ {
l[i], r[i] = 1, 1
}
for i := 1; i < n; i ++ {
if w[i - 1] < w[i] {
l[i] = max(l[i], l[i - 1] + 1)
}
}
for i := n - 2; i >= 0; i -- {
if w[i + 1] < w[i] {
r[i] = max(r[i], r[i + 1] + 1)
}
}
ans := 0
for i := 0; i < n; i ++ {
ans += max(l[i], r[i])
}
return ans
}
func singleNumber(nums []int) int {
ans := 0
for _, x := range nums {
ans ^= x
}
return ans
}
func singleNumber(nums []int) int {
ans := int32(0)
for i := 0; i < 32; i ++ {
cnt := int32(0)
for _, x := range nums {
cnt += int32(x) >> i & 1
}
ans |= (cnt % 3) << i
}
return int(ans)
}
func copyRandomList(head *Node) *Node {
if head == nil {
return nil
}
mp := map[*Node]*Node{}
p := head
for p != nil {
mp[p] = &Node{Val: p.Val}
p = p.Next
}
for s, d := range mp {
if s.Next != nil {
d.Next = mp[s.Next]
}
if s.Random != nil {
d.Random = mp[s.Random]
}
}
return mp[head]
}
func copyRandomList(head *Node) *Node {
if head == nil {
return nil
}
p := head
for p != nil {
q := &Node{Val: p.Val}
q.Next = p.Next
p.Next = q
p = p.Next.Next
}
p = head
for p != nil {
if p.Random != nil {
p.Next.Random = p.Random.Next
}
p = p.Next.Next
}
dummy := &Node{}
cur := dummy
p = head
for p != nil {
q := p.Next
cur.Next = q
cur = cur.Next
p.Next = q.Next
p = p.Next
}
return dummy.Next
}
func wordBreak(s string, wordDict []string) bool {
const base = 13331
S := map[uint64]bool{}
for _, word := range wordDict {
var x uint64 = 0
for _, c := range word {
x = x * base + uint64(c)
}
S[x] = true
}
n := len(s)
s = " " + s
f := make([]bool, n + 1)
f[0] = true
for i := 1; i <= n; i ++ {
for j := 1; j <= i; j ++ {
var x uint64 = 0
for k := j; k <= i; k ++ {
x = x * base + uint64(s[k])
}
if f[j - 1] && S[x] {
f[i] = true
}
}
}
return f[n]
}
func wordBreak(s string, wordDict []string) bool {
const base = 13331
S := map[uint64]bool{}
for _, word := range wordDict {
var x uint64 = 0
for _, c := range word {
x = x * base + uint64(c)
}
S[x] = true
}
n := len(s)
s = " " + s
f := make([]bool, n + 1)
f[0] = true
for i := 0; i < n; i ++ {
if f[i] {
var x uint64 = 0
for j := i + 1; j < n + 1; j ++ {
x = x * base + uint64(s[j])
if _, ok := S[x]; ok {
f[j] = true
}
}
}
}
return f[n]
}
var (
f []bool
ans []string
S map[string]bool
s string
n int
)
func dfs(i int, path string) {
if i == 0 {
path = path[1:] // 去掉最前面开头的那个空格
ans = append(ans, path)
return
}
for j := i; j > 0; j -- {
if f[j - 1] && S[s[j : i + 1]] {
dfs(j - 1, " " + s[j : i + 1] + path)
}
}
}
func wordBreak(_s string, wordDict []string) []string {
ans = []string{}
n = len(_s)
s = " " + _s
S = make(map[string]bool)
for _, x := range wordDict {
S[x] = true
}
f = make([]bool, n + 1)
f[0] = true
for i := 1; i <= n; i ++ { // 从前往后预处理出f[]数组
for j := 1; j <= i; j ++ {
if f[j - 1] && S[s[j : i + 1]] {
f[i] = true
break
}
}
}
dfs(n, "")
return ans
}
var (
f []bool
ans []string
S map[string]bool
s string
n int
)
func dfs(i int, path string) {
if i >= n + 1 {
path = path[:len(path) - 1] // 去掉后面的那个空格
ans = append(ans, path)
return
}
for j := i; j < n + 1; j ++ {
if f[j + 1] && S[s[i : j + 1]] {
dfs(j + 1, path + s[i : j + 1] + " ")
}
}
}
func wordBreak(_s string, wordDict []string) []string {
ans = []string{}
n = len(_s)
s = " " + _s
S = make(map[string]bool)
for _, x := range wordDict {
S[x] = true
}
f = make([]bool, n + 2)
f[n + 1] = true
for i := n; i > 0; i -- { // 从后往前预处理f[]数组
for j := i; j < n + 1; j ++ {
if f[j + 1] && S[s[i : j + 1]] {
f[i] = true
break
}
}
}
dfs(1, "")
return ans
}
func wordBreak(s string, wordDict []string) []string {
S := make(map[string]struct{})
for _, word := range wordDict {
S[word] = struct{}{}
}
n := len(s)
s = " " + s // 在字符串前添加一个空格来简化索引处理
f := make([]bool, n + 1)
f[0] = true
// 使用一个二维切片来存储所有可能的解
ans := make([][]string, n + 1)
ans[0] = append(ans[0], "")
for i := 1; i <= n; i ++ {
for j := i; j > 0; j -- {
if f[j - 1] {
x := s[j : i + 1]
if _, ok := S[x]; ok {
f[i] = true
for _, str := range ans[j - 1] {
space := " "
if str == "" {
space = ""
}
ans[i] = append(ans[i], str + space + x)
}
}
}
}
}
return ans[n]
}
func hasCycle(head *ListNode) bool {
if head == nil || head.Next == nil {
return false
}
slow, fast := head, head
for fast != nil && fast.Next != nil {
slow = slow.Next
fast = fast.Next.Next
if slow == fast {
return true
}
}
return false
}
func detectCycle(head *ListNode) *ListNode {
if head == nil || head.Next == nil {
return nil
}
slow, fast := head, head
for fast != nil && fast.Next != nil {
slow = slow.Next
fast = fast.Next.Next
if slow == fast {
slow = head
for slow != fast {
slow = slow.Next
fast = fast.Next
}
return slow
}
}
return nil
}
func getMid(head *ListNode) *ListNode {
slow, fast := head, head
for fast != nil && fast.Next != nil {
slow = slow.Next
fast = fast.Next.Next
}
return slow
}
func reverseList(head *ListNode) *ListNode {
var pre *ListNode = nil
cur := head
for cur != nil {
nxt := cur.Next
cur.Next = pre
pre = cur
cur = nxt
}
return pre
}
func reorderList(head *ListNode) {
mid := getMid(head)
l1, l2 := head, reverseList(mid)
for l2.Next != nil {
nxt1, nxt2 := l1.Next, l2.Next
l1.Next = l2
l2.Next = nxt1
l1, l2 = nxt1, nxt2
}
}
var ans []int
func dfs(root *TreeNode) {
if root == nil {
return
}
ans = append(ans, root.Val)
if root.Left != nil {
dfs(root.Left)
}
if root.Right != nil {
dfs(root.Right)
}
}
func preorderTraversal(root *TreeNode) []int {
if root == nil {
return []int{}
}
ans = []int{}
dfs(root)
return ans
}
func preorderTraversal(root *TreeNode) []int {
if root == nil {
return nil
}
ans, stk := []int{}, []*TreeNode{}
stk = append(stk, root)
for len(stk) > 0 {
t := stk[len(stk) - 1]
stk = stk[:len(stk) - 1]
ans = append(ans, t.Val)
if t.Right != nil {
stk = append(stk, t.Right)
}
if t.Left != nil {
stk = append(stk, t.Left)
}
}
return ans
}
func preorderTraversal(root *TreeNode) []int {
if root == nil {
return nil
}
ans := []int{}
for root != nil {
if root.Left == nil {
ans = append(ans, root.Val)
root = root.Right
} else {
p := root.Left
for p.Right != nil && p.Right != root {
p = p.Right
}
if p.Right == nil {
p.Right = root
ans = append(ans, root.Val)
root = root.Left
} else {
p.Right = nil
root = root.Right
}
}
}
return ans
}
var ans []int
func dfs(root *TreeNode) {
if root == nil {
return
}
if root.Left != nil {
dfs(root.Left)
}
if root.Right != nil {
dfs(root.Right)
}
ans = append(ans, root.Val)
}
func postorderTraversal(root *TreeNode) []int {
if root == nil {
return nil
}
ans = []int{}
dfs(root)
return ans
}
func postorderTraversal(root *TreeNode) []int {
if root == nil {
return nil
}
ans, stk := []int{}, []*TreeNode{}
stk = append(stk, root)
for len(stk) > 0 {
t := stk[len(stk) - 1]
stk = stk[:len(stk) - 1]
ans = append(ans, t.Val)
if t.Left != nil {
stk = append(stk, t.Left)
}
if t.Right != nil {
stk = append(stk, t.Right)
}
}
for i, j := 0, len(ans) - 1; i < j; i, j = i + 1, j - 1 {
ans[i], ans[j] = ans[j], ans[i]
}
return ans
}
func postorderTraversal(root *TreeNode) []int {
if root == nil {
return nil
}
ans := []int{}
for root != nil {
if root.Right == nil {
ans = append(ans, root.Val)
root = root.Left
} else {
p := root.Right
for p.Left != nil && p.Left != root {
p = p.Left
}
if p.Left == nil {
p.Left = root
ans = append(ans, root.Val)
root = root.Right
} else {
p.Left = nil
root = root.Left
}
}
}
for i, j := 0, len(ans) - 1; i < j; i, j = i + 1, j - 1 {
ans[i], ans[j] = ans[j], ans[i]
}
return ans
}
class LRUCache {
public:
struct Node {
int key, val;
Node *prior, *next;
Node(int _key, int _val): key(_key), val(_val), prior(nullptr), next(nullptr) {}
} *L, *R;
unordered_map mp;
int n;
void del(Node *p) {
p->prior->next = p->next;
p->next->prior = p->prior;
}
void ins(Node *p) {
p->prior = L;
p->next = L->next;
L->next->prior = p;
L->next = p;
}
LRUCache(int capacity) {
n = capacity;
L = new Node(-1, -1), R = new Node(-1, -1);
L->next = R, R->prior = L;
}
int get(int key) {
if (!mp.count(key)) return -1;
auto p = mp[key];
del(p), ins(p);
return p->val;
}
void put(int key, int value) {
if (mp.count(key)) {
auto p = mp[key];
p->val = value;
del(p), ins(p);
} else {
if (mp.size() == n) {
auto p = R->prior;
del(p);
mp.erase(p->key);
delete p;
}
auto p = new Node(key, value);
mp[key] = p;
ins(p);
}
}
};
func insertionSortList(head *ListNode) *ListNode {
dummy := &ListNode{}
p := head
for p != nil {
cur := dummy
nxt := p.Next
for cur.Next != nil && cur.Next.Val <= p.Val {
cur = cur.Next
}
p.Next = cur.Next
cur.Next = p
p = nxt
}
return dummy.Next
}
func sortList(head *ListNode) *ListNode {
if head == nil {
return nil
}
n := 0
for p := head; p != nil; p = p.Next {
n ++
}
dummy := &ListNode{Val: -1, Next: head}
for i := 1; i < n; i <<= 1 {
cur := dummy
for j := 1; j + i <= n; j += 2 * i {
p := cur.Next
q := p
for k := 0; k < i; k ++ {
q = q.Next
}
x, y := 0, 0
for p != nil && q != nil && x < i && y < i {
if p.Val <= q.Val {
cur.Next = p
cur = cur.Next
p = p.Next
x ++
} else {
cur.Next = q
cur = cur.Next
q = q.Next
y ++
}
}
for p != nil && x < i {
cur.Next = p
cur = cur.Next
p = p.Next
x ++
}
for q != nil && y < i {
cur.Next = q
cur = cur.Next
q = q.Next
y ++
}
cur.Next = q
}
}
return dummy.Next
}
func maxPoints(points [][]int) int {
ans := 0
for _, p := range points {
verPoints, samePoints := 0, 0
mp := map[float64]int{}
for _, q := range points {
if p[0] == q[0] && p[1] == q[1] {
samePoints ++
} else if p[0] == q[0] {
verPoints ++
} else {
k := float64(q[1] - p[1]) / float64(q[0] - p[0])
mp[k] ++
}
}
cnt := verPoints
for _, v := range mp {
cnt = max(cnt, v)
}
ans = max(ans, cnt + samePoints)
}
return ans
}
func maxPoints(points [][]int) int {
ans := 0
for _, p := range points {
mp := map[string]int{}
samePoints, t := 0, 0
for _, q := range points {
dy, dx := q[1] - p[1], q[0] - p[0]
if dy == 0 && dx == 0 {
samePoints ++
continue
}
GCD := gcd(dy, dx)
if GCD != 0 {
dy /= GCD
dx /= GCD
}
slope := fmt.Sprintf("%d/%d", dy, dx)
mp[slope] ++
t = max(t, mp[slope])
}
ans = max(ans, t + samePoints)
}
return ans
}
func gcd(a, b int) int {
if b == 0 {
return a
}
return gcd(b, a % b)
}
func evalRPN(tokens []string) int {
stk := []int{}
for _, s := range tokens {
if s == "+" || s == "-" || s == "*" || s == "/" {
b, a := stk[len(stk) - 1], stk[len(stk) - 2]
stk = stk[:len(stk) - 2]
if s == "+" {
a += b
} else if s == "-" {
a -= b
} else if s == "*" {
a *= b
} else if s == "/" {
a /= b
}
stk = append(stk, a)
} else {
if x, err := strconv.Atoi(s); err == nil {
stk = append(stk, x)
}
}
}
return stk[len(stk) - 1]
}
func reverseWords(s string) string {
ans := ""
i, j := len(s) - 1, len(s) - 1
for i >= 0 {
for i >= 0 && s[i] == ' ' {
i --
}
if i < 0 {
break
}
j = i
for i >= 0 && s[i] != ' ' {
i --
}
if len(ans) > 0 {
ans += " "
}
ans += s[i + 1 : j + 1]
}
return ans
}
func maxProduct(nums []int) int {
n := len(nums)
f, g := make([]int, n), make([]int, n)
f[0], g[0] = nums[0], nums[0]
var ans int = f[0]
for i := 1; i < n; i ++ {
if nums[i] >= 0 {
f[i] = max(nums[i], f[i - 1] * nums[i])
g[i] = min(nums[i], g[i - 1] * nums[i])
} else {
f[i] = max(nums[i], g[i - 1] * nums[i])
g[i] = min(nums[i], f[i - 1] * nums[i])
}
ans = max(ans, f[i])
}
return ans
}
func maxProduct(nums []int) int {
ans, f, g := nums[0], nums[0], nums[0]
for i := 1; i < len(nums); i ++ {
a:= nums[i]
fa, ga := f * a, g * a
f = max(a, max(fa, ga))
g = min(a, min(fa, ga))
ans = max(ans, f)
}
return ans
}
func findMin(nums []int) int {
l, r := 0, len(nums) - 1
for l < r {
mid := (l + r) >> 1
if nums[mid] < nums[r] {
r = mid
} else {
l = mid + 1
}
}
return nums[r]
}
func findMin(nums []int) int {
n := len(nums) - 1
for n >= 0 && nums[n] == nums[0] {
n --
}
if n < 0 {
return nums[0]
}
l, r := 0, n
for l < r {
mid := (l + r) >> 1
if nums[mid] <= nums[r] {
r = mid
} else {
l = mid + 1
}
}
return nums[r]
}
class MinStack {
public:
stack> stk;
MinStack() {}
void push(int x) {
if (stk.empty()) stk.push({x, x});
else stk.push({x, min(x, stk.top().second)});
}
void pop() {
stk.pop();
}
int top() {
return stk.top().first;
}
int getMin() {
return stk.top().second;
}
};
class MinStack {
public:
stack stk, min_stk;
MinStack() {}
void push(int x) {
stk.push(x);
if (min_stk.empty() || x <= min_stk.top()) {
min_stk.push(x);
}
}
void pop() {
if (stk.top() == min_stk.top()) min_stk.pop();
stk.pop();
}
int top() {
return stk.top();
}
int getMin() {
return min_stk.top();
}
};
// 时空复杂度都为O(1)
class MinStack {
public:
using LL = long long ;
vector stk; // 注意栈内是LL 而不是int
int minVal = INT_MAX;
MinStack() {}
void push(int val) {
if (stk.empty()) minVal = val;
// 注意val - minVal可能会导致溢出 这里转为LL
stk.push_back((LL)val - minVal);
if (val < minVal) minVal = val;
}
void pop() {
LL x = stk.back(); stk.pop_back();
if (x < 0) minVal -= x;
}
int top() { // 这里返回值也可以写LL
LL x = stk.back();
return x >= 0 ? minVal + x : minVal;
}
int getMin() { // 这里返回值也可以写LL
return minVal;
}
};
func dfs(x, y *TreeNode) *TreeNode {
var rt *TreeNode
if y.Left != nil {
rt = dfs(y, y.Left)
} else {
rt = y
}
if x != nil {
z := x.Right
y.Left, y.Right = z, x
x.Left, x.Right = nil, nil
}
return rt
}
func upsideDownBinaryTree(root *TreeNode) *TreeNode {
if root == nil {
return nil
}
return dfs(nil, root)
}
func upsideDownBinaryTree(root *TreeNode) *TreeNode {
if root == nil {
return nil
}
var p *TreeNode = nil
var p_rc *TreeNode = nil
for root != nil {
l, r := root.Left, root.Right
root.Left, root.Right = p_rc, p
p, root, p_rc = root, l, r
}
return p
}
func lengthOfLongestSubstringTwoDistinct(s string) int {
ans, cnt := 0, 0
mp := map[byte]int{}
for l, r := 0, 0; r < len(s); r ++ {
if mp[s[r]] == 0 {
cnt ++
}
mp[s[r]] ++
for cnt > 2 {
mp[s[l]] --
if mp[s[l]] == 0 {
cnt --
}
l ++
}
ans = max(ans, r - l + 1)
}
return ans
}
func getIntersectionNode(headA, headB *ListNode) *ListNode {
p, q := headA, headB
for p != q {
if p != nil {
p = p.Next
} else {
p = headB
}
if q != nil {
q = q.Next
} else {
q = headA
}
}
return p
}
func isOneEditDistance(s string, t string) bool {
m, n := len(s), len(t)
if m > n {
return isOneEditDistance(t, s)
}
if n - m > 1 {
return false
}
for i := 0; i < m; i ++ {
if s[i] != t[i] {
if m == n {
return s[i + 1:] == t[i + 1:]
} else {
return s[i:] == t[i + 1:]
}
}
}
return m + 1 == n
}
// 二分
func findPeakElement(nums []int) int {
l, r := 0, len(nums) - 1
for l < r {
mid := (l + r) >> 1
if nums[mid] > nums[mid + 1] {
r = mid
} else {
l = mid + 1
}
}
return l
}
// 三分
func findPeakElement(nums []int) int {
l, r := 0, len(nums) - 1
for l < r {
m1 := (l + r) >> 1
m2 := m1 + 1
// m1 := l + (r - l) / 3
// m2 := r - (r - l) / 3
if nums[m1] < nums[m2] {
l = m1 + 1
} else {
r = m2 - 1
}
}
return l
}
func findMissingRanges(nums []int, lower int, upper int) [][]int {
nums = append([]int{lower - 1}, nums...)
nums = append(nums, upper + 1)
ans := [][]int{}
for i := 1; i < len(nums); i ++ {
if nums[i] - nums[i - 1] > 1 {
ans = append(ans, []int{nums[i - 1] + 1, nums[i] - 1})
}
}
return ans
}
func maximumGap(nums []int) int {
n := len(nums)
if n < 2 {
return 0
}
radix, maxVal := 1, 0
for _, x := range nums {
maxVal = max(maxVal, x)
}
tmp := make([]int, n)
for radix <= maxVal {
cnt := make([]int, 10)
for _, x := range nums {
digit := (x / radix) % 10
cnt[digit] ++
}
for i := 1; i < 10; i ++ {
cnt[i] += cnt[i - 1]
}
for i := n - 1; i >= 0; i -- {
digit := (nums[i] / radix) % 10
cnt[digit] --
tmp[cnt[digit]] = nums[i]
}
copy(nums, tmp)
radix *= 10
}
ans := 0
for i := 1; i < n; i ++ {
ans = max(ans, nums[i] - nums[i - 1])
}
return ans
}
func compareVersion(v1, v2 string) int {
n, m := len(v1), len(v2)
for i, j := 0, 0; i < n || j < m; i, j = i + 1, j + 1 {
x, y := 0, 0
for i < n && v1[i] != '.' {
x = x * 10 + int(v1[i]-'0')
i ++
}
for j < m && v2[j] != '.' {
y = y * 10 + int(v2[j]-'0')
j ++
}
if x > y {
return 1
}
if x < y {
return -1
}
}
return 0
}
func fractionToDecimal(numerator int, denominator int) string {
x, y := int64(numerator), int64(denominator)
if x % y == 0 {
return fmt.Sprintf("%d", x / y)
}
ans := ""
if (x < 0) != (y < 0) {
ans += "-"
}
x = abs(x)
y = abs(y)
ans += fmt.Sprintf("%d.", x / y)
x %= y;
mp := map[int64]int{}
for x > 0 {
mp[x] = len(ans)
x *= 10
ans += fmt.Sprintf("%d", x / y)
x %= y
if i, ok := mp[x]; ok {
ans = ans[:i] + "(" + ans[i:] + ")"
break
}
}
return ans
}
func abs(x int64) int64 {
if x < 0 {
return -x
}
return x
}
func twoSum(nums []int, target int) []int {
l, r := 0, len(nums) - 1
for l < r {
s := nums[l] + nums[r]
if s == target {
return []int{l + 1, r + 1}
} else if s < target {
l ++
} else {
r --
}
}
return []int{-1, -1}
}
func convertToTitle(x int) string {
ans := []byte{}
for x > 0 {
x --
ans = append(ans, 'A' + byte(x % 26))
x /= 26
}
for i, j := 0, len(ans) - 1; i < j; i, j = i + 1, j - 1 {
ans[i], ans[j] = ans[j], ans[i]
}
return string(ans)
}
func majorityElement(nums []int) int {
p1, c1, n := 0, 0, len(nums)
for _, x := range nums {
if c1 > 0 && x == p1 {
c1 ++
} else if c1 == 0 {
p1 = x
c1 = 1
} else {
c1 --
}
}
c1 = 0
for _, x := range nums {
if x == p1 {
c1 ++
}
}
if c1 > n / 2 {
return p1
}
return 0
}
type TwoSum struct {
mp map[int]int
}
func Constructor() TwoSum {
return TwoSum{mp: make(map[int]int)}
}
func (this *TwoSum) Add(x int) {
this.mp[x] ++
}
func (this *TwoSum) Find(value int) bool {
for x, cnt := range this.mp {
y := value - x
if y != x {
if _, ok := this.mp[y]; ok {
return true
}
} else if cnt >= 2 {
return true
}
}
return false
}
func titleToNumber(s string) int {
ans := 0
for _, c := range s {
ans = ans * 26 + (int(c - 'A') + 1)
}
return ans
}
// 迭代
func trailingZeroes(n int) int {
ans, p := 0, 5
for n > 0 {
ans += n / p
n /= p
}
return ans
}
// 递归
class Solution {
public:
int p = 5;
int trailingZeroes(int n) {
if (n < p) return 0;
return n / p + trailingZeroes(n / p);
}
};
type BSTIterator struct {
root *TreeNode
stk []*TreeNode
}
func Constructor(rt *TreeNode) BSTIterator {
return BSTIterator{root: rt}
}
func (this *BSTIterator) Next() int {
for this.root != nil {
this.stk = append(this.stk, this.root)
this.root = this.root.Left
}
this.root = this.stk[len(this.stk) - 1]
this.stk = this.stk[ : len(this.stk) - 1]
x := this.root.Val
this.root = this.root.Right
return x
}
func (this *BSTIterator) HasNext() bool {
return len(this.stk) > 0 || this.root != nil
}
func calculateMinimumHP(w [][]int) int {
n, m := len(w), len(w[0])
f := make([][]int, n + 1)
for i := 0; i < n + 1; i ++ {
f[i] = make([]int, m + 1)
for j := 0; j < m + 1; j ++ {
f[i][j] = math.MaxInt32
}
}
f[n][m - 1], f[n - 1][m] = 1, 1
for i := n - 1; i >= 0; i -- {
for j := m - 1; j >= 0; j -- {
f[i][j] = max(1, min(f[i + 1][j], f[i][j + 1]) - w[i][j])
}
}
return f[0][0]
}
func calculateMinimumHP(w [][]int) int {
n, m := len(w), len(w[0])
f := make([][]int, n + 1)
for i := 0; i < n + 1; i ++ {
f[i] = make([]int, m + 1)
for j := 0; j < m + 1; j ++ {
f[i][j] = math.MaxInt32
}
}
for i := n - 1; i >= 0; i -- {
for j := m - 1; j >= 0; j -- {
if i == n - 1 && j == m - 1 {
f[i][j] = max(1, 1 - w[i][j])
} else {
if i + 1 < n {
f[i][j] = min(f[i][j], f[i + 1][j] - w[i][j]);
}
if j + 1 < m {
f[i][j] = min(f[i][j], f[i][j + 1] - w[i][j]);
}
f[i][j] = max(1, f[i][j])
}
}
}
return f[0][0]
}
func largestNumber(nums []int) string {
sort.Slice(nums, func(i, j int) bool {
a, b := strconv.Itoa(nums[i]), strconv.Itoa(nums[j])
return a + b > b + a
})
if nums[0] == 0 {
return "0"
}
ans := ""
for _, x := range nums {
ans += strconv.Itoa(x)
}
return ans
}
func findRepeatedDnaSequences(s string) []string {
ans := []string{}
mp := map[string]int{}
for i := 0; i + 9 < len(s); i ++ {
t := s[i : i + 10]
mp[t] ++
if mp[t] == 2 {
ans = append(ans, t)
}
}
return ans
}
const base = 13331
var (
h, p []uint64
)
func get(l, r int) uint64 {
return h[r] - h[l - 1] * p[r - l + 1]
}
func findRepeatedDnaSequences(s string) []string {
n := len(s)
s = " " + s
h, p = make([]uint64, n + 1), make([]uint64, n + 1)
p[0] = 1
for i := 1; i <= n; i++ {
h[i] = h[i - 1] * base + uint64(s[i])
p[i] = p[i - 1] * base
}
var ans []string
mp := map[uint64]int{}
for i := 1; i + 9 < n + 1; i ++ {
x := get(i, i + 9)
mp[x] ++
if mp[x] == 2 {
ans = append(ans, s[i : i + 10])
}
}
return ans
}
func maxProfit(k int, prices []int) int {
n := len(prices)
prices = append([]int{-1}, prices...)
f := make([][][]int, n + 1)
for i := range f {
f[i] = make([][]int, k + 1)
for j := range f[i] {
f[i][j] = make([]int, 2)
}
}
for j := 0; j <= k; j ++ {
f[0][j][1] = math.MinInt
}
for i := 1; i <= n; i ++ {
for j := 1; j <= k; j ++ {
f[i][j][0] = max(f[i - 1][j][0], f[i - 1][j][1] + prices[i])
f[i][j][1] = max(f[i - 1][j][1], f[i - 1][j-1][0] - prices[i])
}
}
return f[n][k][0]
}
func maxProfit(k int, prices []int) int {
n := len(prices)
prices = append([]int{-1}, prices...)
f := make([][]int, k + 1)
for i := range f {
f[i] = make([]int, 2)
}
for j := 0; j <= k; j ++ {
f[j][1] = math.MinInt
}
for i := 1; i <= n; i ++ {
for j := 1; j <= k; j ++ {
f[j][0] = max(f[j][0], f[j][1] + prices[i])
f[j][1] = max(f[j][1], f[j - 1][0] - prices[i])
}
}
return f[k][0]
}
// 时间复杂度O(n) 空间复杂度O(n)
func rotate(nums []int, k int) {
n := len(nums)
tmp := make([]int, n)
for i := 0; i < n; i ++ {
tmp[(i + k) % n] = nums[i]
}
copy(nums, tmp)
}
// 时间复杂度O(n) 空间复杂度O(1)
func rotate(nums []int, k int) {
n := len(nums)
k %= n
reverse(nums, 0, n - 1)
reverse(nums, 0, k - 1)
reverse(nums, k, n - 1)
}
func reverse(nums []int, l, r int) {
for l < r {
nums[l], nums[r] = nums[r], nums[l]
l ++
r --
}
}
// //时间复杂度O(n) 空间复杂度O(1)
func rotate(nums []int, k int) {
n := len(nums)
k %= n
cnt := gcd(k, n)
for start := 0; start < cnt; start ++ {
cur, prev := start, nums[start]
for {
nxt := (cur + k) % n
nums[nxt], prev = prev, nums[nxt]
cur = nxt
if cur == start {
break
}
}
}
}
func gcd(a, b int) int {
if b == 0 {
return a
}
return gcd(b, a % b)
}
func reverseBits(n uint32) uint32 {
var ans uint32
for i := 0; i < 32; i ++ {
ans = (ans << 1) + (n >> i & 1)
}
return ans
}
func hammingWeight(n uint32) int {
ans := 0
for i := 0; i < 32; i ++ {
ans += int(n >> i) & 1
}
return ans
}
func hammingWeight(n uint32) int {
ans := 0
for n > 0 {
n -= n & -n
ans ++
}
return ans
}
func rob(nums []int) int {
n := len(nums)
if n == 0 {
return 0
}
if n == 1 {
return nums[0]
}
f := make([]int, n)
f[0], f[1] = nums[0], max(nums[0], nums[1])
for i := 2; i < n; i ++ {
f[i] = max(f[i - 1], f[i - 2] + nums[i])
}
return f[n - 1]
}
func rob(nums []int) int {
n := len(nums)
if n == 0 {
return 0
}
if n == 1 {
return nums[0]
}
a, b := nums[0], max(nums[0], nums[1])
for i := 2; i < n; i ++ {
tmp := b
b = max(b, a + nums[i])
a = tmp
}
return b
}
var ans []int
func dfs(root *TreeNode, dep int) {
if root == nil {
return
}
if dep == len(ans) {
ans = append(ans, root.Val)
}
if root.Right != nil {
dfs(root.Right, dep + 1)
}
if root.Left != nil {
dfs(root.Left, dep + 1)
}
}
func rightSideView(root *TreeNode) []int {
if root == nil {
return []int{}
}
ans = []int{}
dfs(root, 0)
return ans
}
/**
* Definition for a binary tree node.
* type TreeNode struct {
* Val int
* Left *TreeNode
* Right *TreeNode
* }
*/
func rightSideView(root *TreeNode) []int {
var ans []int
if root == nil {
return ans
}
q := []*TreeNode{root}
for len(q) > 0 {
s := len(q)
for i := 0; i < s; i ++ {
t := q[0]
q = q[1:]
if i == s - 1 { // 当前层的最后一个节点
ans = append(ans, t.Val)
}
if t.Left != nil {
q = append(q, t.Left)
}
if t.Right != nil {
q = append(q, t.Right)
}
}
}
return ans
}
type PII struct {
x, y int
}
var (
g [][]byte
n, m int
dx = []int{-1, 0, 1, 0}
dy = []int{0, 1, 0, -1}
)
func bfs(sx, sy int) {
q := []PII{{sx, sy}}
g[sx][sy] = '#' // 标记点(sx,sy)已经被访问过了
for len(q) > 0 {
t := q[0]
q = q[1:]
for i := 0; i < 4; i ++ {
a, b := t.x + dx[i], t.y + dy[i]
if a < 0 || a >= n || b < 0 || b >= m || g[a][b] == '#' || g[a][b] == '0' {
continue
}
q = append(q, PII{a, b})
g[a][b] = '#' // 标记点(a,b)已经被访问过了
}
}
}
func numIslands(grid [][]byte) int {
g = grid
n, m = len(g), len(g[0])
if n == 0 || m == 0 {
return 0
}
ans := 0
for i := 0; i < n; i ++ {
for j := 0; j < m; j ++ {
// 如果点(i,j)没有被访问过并且它是陆地
if g[i][j] != '#' && g[i][j] == '1' {
bfs(i, j)
ans ++
}
}
}
return ans
}
var (
g [][]byte
n, m int
dx = []int{-1, 0, 1, 0}
dy = []int{0, 1, 0, -1}
)
func dfs(x, y int) {
g[x][y] = '#'
for i := 0; i < 4; i ++ {
a, b := x + dx[i], y + dy[i]
if a < 0 || a >= n || b < 0 || b >= m || g[a][b] != '1' {
continue
}
dfs(a, b)
}
}
func numIslands(grid [][]byte) int {
g = grid
n, m = len(g), len(g[0])
if n == 0 || m == 0 {
return 0
}
ans := 0
for i := 0; i < n; i ++ {
for j := 0; j < m; j ++ {
// 如果点(i,j)没有被访问过并且它是陆地
if g[i][j] != '#' && g[i][j] == '1' {
dfs(i, j)
ans ++
}
}
}
return ans
}