本篇博客是用Go语言编写的详尽简洁代码,这里没有写算法思路,若要看具体思路,请移步力扣官网查看相关高赞题解。本篇博客的特点是代码简洁明了,包含多种写法,适合读者后期复盘巩固,加深理解。这一百题是面试高频题,建议读者认真阅读,背诵记忆。欢迎点赞+收藏+关注~~
func rangeBitwiseAnd(l int, r int) int {
i := 0
for l < r {
l >>= 1
r >>= 1
i ++
}
return l << i
}
func rangeBitwiseAnd(l int, r int) int {
for l < r {
r = r & (r - 1)
}
return r // 注意是返回r而不能是返回l
}
func get(n int) int {
ans := 0
for n > 0 {
ans += (n % 10) * (n % 10)
n /= 10
}
return ans
}
func isHappy(n int) bool {
slow, fast := n, get(n)
for slow != fast {
slow = get(slow)
fast = get(get(fast))
}
return slow == 1
}
func get(n int) int {
ans := 0
for n > 0 {
ans += (n % 10) * (n % 10)
n /= 10
}
return ans
}
func isHappy(n int) bool {
slow, fast := n, n
for {
slow = get(slow)
fast = get(get(fast))
if slow == fast {
break
}
}
return slow == 1
}
func removeElements(head *ListNode, x int) *ListNode {
if head == nil {
return nil
}
head.Next = removeElements(head.Next, x)
if head.Val == x {
return head.Next
}
return head
}
func removeElements(head *ListNode, x int) *ListNode {
if head == nil {
return nil
}
dummy := &ListNode{-1, head}
var cur *ListNode = dummy
for cur.Next != nil {
if cur.Next.Val == x {
cur.Next = cur.Next.Next
} else {
cur = cur.Next
}
}
return dummy.Next
}
func countPrimes(n int) int {
st := make([]bool, n + 1)
primes := []int{}
for i := 2; i < n; i ++ {
if !st[i] {
primes = append(primes, i)
}
for j := 0; j < len(primes) && primes[j] <= n / i; j ++ {
st[i * primes[j]] = true
if i % primes[j] == 0 {
break
}
}
}
return len(primes)
}
func isIsomorphic(s string, t string) bool {
n, m := len(s), len(t)
if n != m {
return false
}
st, ts := make(map[byte]byte), make(map[byte]byte)
for i := 0; i < n; i ++ {
x, y := s[i], t[i]
if (st[x] != 0 && st[x] != y) || (ts[y] != 0 && ts[y] != x) {
return false
}
st[x] = y
ts[y] = x
}
return true
}
func reverseList(head *ListNode) *ListNode {
if head == nil || head.Next == nil {
return head
}
last := reverseList(head.Next)
head.Next.Next = head
head.Next = nil
return last
}
func reverseList(head *ListNode) *ListNode {
if head == nil || head.Next == nil {
return head
}
var pre, cur *ListNode = nil, head
for cur != nil {
nxt := cur.Next
cur.Next = pre
pre = cur
cur = nxt
}
return pre
}
func canFinish(n int, edges [][]int) bool {
d := make([]int, n)
g := make([][]int, n)
for _, e := range edges {
a, b := e[1], e[0]
g[a] = append(g[a], b)
d[b] ++
}
q := []int{}
for i := 0; i < n; i ++ {
if d[i] == 0 {
q = append(q, i)
}
}
cnt := 0
for len(q) > 0 {
t := q[0]
q = q[1:]
cnt ++
for _, i := range g[t] {
d[i] --
if d[i] == 0 {
q = append(q, i)
}
}
}
return cnt == n
}
type Trie struct {
isEnd bool
tr [26]*Trie
}
func Constructor() Trie {
return Trie{}
}
func (root *Trie) Insert(word string) {
p := root
for _, c := range word {
u := c - 'a'
if p.tr[u] == nil {
p.tr[u] = &Trie{}
}
p = p.tr[u]
}
p.isEnd = true
}
func (root *Trie) Search(word string) bool {
p := root
for _, c := range word {
u := c - 'a'
if p.tr[u] == nil {
return false
}
p = p.tr[u]
}
return p.isEnd
}
func (root *Trie) StartsWith(prefix string) bool {
p := root
for _, c := range prefix {
u := c - 'a'
if p.tr[u] == nil {
return false
}
p = p.tr[u]
}
return true
}
func minSubArrayLen(target int, nums []int) int {
n := len(nums)
if n == 0 {
return 0
}
l, sum, ans := 0, 0, math.MaxInt32
for r, x := range nums {
sum += x
for sum >= target {
ans = min(ans, r - l + 1)
sum -= nums[l]
l ++
}
}
if ans == math.MaxInt32 {
return 0
}
return ans
}
func findOrder(n int, edges [][]int) []int {
d := make([]int, n)
g := make([][]int, n)
for _, e := range edges {
a, b := e[1], e[0]
d[b] ++
g[a] = append(g[a], b)
}
q := []int{}
for i := 0; i < n; i ++ {
if d[i] == 0 {
q = append(q, i)
}
}
ans := []int{}
for len(q) > 0 {
t := q[0]
q = q[1:]
ans = append(ans, t)
for _, i := range g[t] {
d[i] --
if d[i] == 0 {
q = append(q, i)
}
}
}
if len(ans) < n {
return []int{}
}
return ans
}
type Trie struct {
isEnd bool
tr [26]*Trie
}
type WordDictionary struct {
root *Trie
}
func Constructor() WordDictionary {
return WordDictionary{&Trie{}}
}
func (w *WordDictionary) AddWord(word string) {
p := w.root
for _, c := range word {
u := c - 'a'
if p.tr[u] == nil {
p.tr[u] = &Trie{}
}
p = p.tr[u]
}
p.isEnd = true
}
func (w *WordDictionary) Search(word string) bool {
return dfs(w.root, word, 0)
}
func dfs(p *Trie, word string, i int) bool {
if p == nil {
return false
}
if i >= len(word) {
return p.isEnd
}
if word[i] != '.' {
return dfs(p.tr[word[i] - 'a'], word, i + 1)
} else {
for u := 0; u < 26; u ++ {
if dfs(p.tr[u], word, i + 1) {
return true
}
}
}
return false
}
type Node struct {
word string
tr [26]*Node
}
var (
dx = []int{-1, 0, 1, 0}
dy = []int{0, 1, 0, -1}
g [][]byte
s map[string]struct{}
root *Node
n, m int
)
func ins(word string) {
p := root
for _, c := range word {
u := c - 'a'
if p.tr[u] == nil {
p.tr[u] = &Node{}
}
p = p.tr[u]
}
p.word = word
}
func dfs(p *Node, x int, y int) {
if p.word != "" {
s[p.word] = struct{}{}
}
t := g[x][y]
g[x][y] = '#'
for i := 0; i < 4; i ++ {
a := x + dx[i]
b := y + dy[i]
if a >= 0 && a < n && b >= 0 && b < m && g[a][b] != '#' {
u := g[a][b] - 'a'
if p.tr[u] != nil {
dfs(p.tr[u], a, b)
}
}
}
g[x][y] = t
}
func findWords(board [][]byte, words []string) []string {
g = board
n, m = len(g), len(g[0])
s = make(map[string]struct{})
root = &Node{}
for _, word := range words {
ins(word)
}
for i := 0; i < n; i ++ {
for j := 0; j < m; j ++ {
u := board[i][j] - 'a'
if root.tr[u] != nil {
dfs(root.tr[u], i, j)
}
}
}
var ans []string
for word := range s {
ans = append(ans, word)
}
return ans
}
func rob(nums []int) int {
n := len(nums)
if n == 0 {
return 0
}
if n == 1 {
return nums[0]
}
if n == 2 {
return max(nums[0], nums[1])
}
f := make([]int, n)
ans := 0
f[0], f[1] = nums[0], max(nums[0], nums[1])
for i := 2; i < n - 1; i ++ {
f[i] = max(f[i - 1], f[i - 2] + nums[i])
}
ans = max(ans, f[n - 2])
f[0], f[1] = 0, nums[1]
for i := 2; i < n; i ++ {
f[i] = max(f[i - 1], f[i - 2] + nums[i])
}
ans = max(ans, f[n - 1])
return ans
}
func max(x, y int) int {
if x > y {
return x
}
return y
}
func rob(nums []int) int {
n := len(nums)
if n == 0 {
return 0
}
if n == 1 {
return nums[0]
}
if n == 2 {
return max(nums[0], nums[1])
}
one := robRange(nums, 0, n - 2)
last := robRange(nums, 1, n - 1)
return max(one, last)
}
func robRange(nums []int, l, r int) int {
a, b := nums[l], max(nums[l], nums[l + 1])
for i := l + 2; i <= r; i ++ {
tmp := b
b = max(b, a + nums[i])
a = tmp
}
return b
}
func max(x, y int) int {
if x > y {
return x
}
return y
}
func reverse(str string) string {
s := []rune(str)
for i, j := 0, len(s) - 1; i < j; i, j = i + 1, j - 1 {
s[i], s[j] = s[j], s[i]
}
return string(s)
}
func shortestPalindrome(s string) string {
n := len(s)
t := reverse(s)
str := s
s = " " + s + "#" + t
ne := make([]int, 2 * n + 2)
for i, j := 2, 0; i <= 2 * n + 1; i ++ {
for j > 0 && s[i] != s[j + 1] {
j = ne[j]
}
if s[i] == s[j + 1] {
j ++
}
ne[i] = j
}
x := ne[2 * n + 1] // 最长公共回文前后缀的长度x
front := reverse(s[x + 1 : n + 1]) // 反转从起点x+1开始,长度为n-x的这段子串
return front + str
}
func reverse(str string) string {
s := []rune(str)
for i, j := 0, len(s) - 1; i < j; i, j = i + 1, j - 1{
s[i], s[j] = s[j], s[i]
}
return string(s)
}
func shortestPalindrome(s string) string {
n, pos := len(s), -1
var left, right, mul uint64 = 0, 0, 1
const base = 13331
for i := 0; i < n; i ++ {
left = left * base + uint64(s[i])
right += uint64(s[i]) * mul
if left == right {
pos = i
}
mul *= base
}
t := s[pos + 1 : ]
front := reverse(t)
return front + s
}
// 使用优先队列,时间复杂度是O(nlogn),但其实并不符合题意
class Solution {
public:
int findKthLargest(vector<int>& nums, int k) {
priority_queue<int, vector<int>, greater<int>> q;
for (auto &x : nums) {
if (q.size() < k || q.top() < x) q.push(x);
if (q.size() > k) q.pop();
}
return q.top();
}
};
// 快速选择,时间复杂度是O(n),符合题意
class Solution {
public:
int quick_select(vector<int>& nums, int l, int r, int k) {
if (l >= r) return nums[r];
swap(nums[l], nums[l + rand() % (r - l + 1)]);
int i = l - 1, j = r + 1, x = nums[l];
while (i < j) {
while (nums[ ++ i] > x) ;
while (nums[ -- j] < x) ;
if (i < j) swap(nums[i], nums[j]);
}
int s = j - l + 1;
if (k <= s) return quick_select(nums, l, j, k);
return quick_select(nums, j + 1, r, k - s);
}
int findKthLargest(vector<int>& nums, int k) {
return quick_select(nums, 0, nums.size() - 1, k);
}
};
var (
ans [][]int
path []int
k, n int
)
func dfs(start, sum int) {
if sum > n {
return
}
if len(path) + (9 - start + 1) < k {
return
}
if len(path) == k && sum == n {
tmp := make([]int, len(path))
copy(tmp, path)
ans = append(ans, tmp)
return
}
for i := start; i <= 9; i ++ {
sum += i
path = append(path, i)
dfs(i + 1, sum)
sum -= i
path = path[: len(path) - 1]
}
}
func combinationSum3(_k int, _n int) [][]int {
k, n = _k, _n
ans, path = [][]int{}, []int{}
dfs(1, 0)
return ans
}
func containsDuplicate(nums []int) bool {
S := map[int]bool{}
for _, x := range nums {
if S[x] {
return true
}
S[x] = true
}
return false
}
class Solution {
public:
vector> getSkyline(vector>& buildings) {
vector> ans;
vector> height;
/*
正负用于判别是左端点还是右端点,同时保证排序后:
1. 左端点相同时,最高的楼排在前面,insert的一定是相同左端点中最大的高度
2. 右端点相同时,最低的楼排在前面,erase的时候不会改变最大高度
*/
for (auto &b : buildings) {
height.push_back({b[0], -b[2]}); // 左端点
height.push_back({b[1], b[2]}); // 右端点
}
sort(height.begin(), height.end()); // 排序
multiset S; // 维护当前最大高度
/*
由于题目中最后的x轴的点算入了答案中,所以可以认为x轴这个也是一个楼
所以这里把x轴也加入到高度里面,也就是在高度的multiset里加入0
*/
S.insert(0); // 保证端点全部删除之后能得到当前最大高度为 0
// preMaxHeight 表示遇到一个端点之前的最大高度
// curMaxHeight 表示遇到一个端点之后的当前最大高度
int preMaxHeight = 0, curMaxHeight = 0;
for (auto &h : height) {
// 左端点
if (h.second < 0) S.insert(-h.second);
// 右端点
else S.erase(S.find(h.second));
curMaxHeight = *S.rbegin();
// 最大高度发生改变,一定是一个关键点,即一个水平线段的左端点
if (curMaxHeight != preMaxHeight) {
ans.push_back({h.first, curMaxHeight});
preMaxHeight = curMaxHeight;
}
}
return ans;
}
};
func containsNearbyDuplicate(nums []int, k int) bool {
mp := map[int]int{}
for i, x := range nums {
_, ok := mp[x]
if ok && abs(i - mp[x]) <= k {
return true
}
mp[x] = i
}
return false
}
func abs(x int) int {
if x <= 0 {
return -x
}
return x
}
class Solution {
public:
using LL = long long;
bool containsNearbyAlmostDuplicate(vector<int>& nums, int k, int t) {
multiset<LL> S;
for (int i = 0; i < nums.size(); ++ i) {
LL x = nums[i];
auto it = S.lower_bound(x - t);
if (it != S.end() && *it <= x + t) return true;
S.insert(x);
// 窗口区间是[i-k, i-1], 所以移除左端点元素就是nums[i - k]
if (i >= k ) S.erase(S.find(nums[i - k]));
}
return false;
}
};
func solve(h []int) int {
n := len(h)
l, r := make([]int, n), make([]int ,n)
stk := []int{}
for i := 0; i < n; i ++ {
for len(stk) > 0 && h[stk[len(stk) - 1]] >= h[i] {
stk = stk[: len(stk) - 1]
}
if len(stk) == 0 {
l[i] = -1
} else {
l[i] = stk[len(stk) - 1]
}
stk = append(stk, i)
}
stk = []int{}
for i := n - 1; i >= 0; i -- {
for len(stk) > 0 && h[stk[len(stk) - 1]] >= h[i] {
stk = stk[: len(stk) - 1]
}
if len(stk) == 0 {
r[i] = n
} else {
r[i] = stk[len(stk) - 1]
}
stk = append(stk, i)
}
ans := 0
for i := 0; i < n; i ++ {
// 区别:这边找到高h[i],宽r[i] - l[i] -1 中最小的作为正方形的边长
x := min(h[i], r[i] - l[i] - 1)
ans = max(ans, x * x)
}
return ans
}
func maximalSquare(g [][]byte) int {
n, m := len(g), len(g[0])
if n == 0 || m == 0 {
return 0
}
s := make([][]int, n)
for i := 0; i < n; i ++ {
s[i] = make([]int, m)
}
for i := 0; i < n; i ++ {
for j := 0; j < m; j ++ {
if g[i][j] == '1' {
if i > 0 {
s[i][j] = s[i - 1][j] + 1
} else {
s[i][j] = 1
}
}
}
}
ans := 0
for i := 0; i < n; i ++ {
ans = max(ans, solve(s[i]))
}
return ans
}
func maximalSquare(g [][]byte) int {
n, m, len := len(g), len(g[0]), 0
if n == 0 || m == 0 {
return 0
}
f := make([][]int, n + 1)
for i := 0; i < n + 1; i ++ {
f[i] = make([]int, m + 1)
}
for i := 1; i <= n; i ++ {
for j := 1; j <= m; j ++ {
if g[i - 1][j - 1] == '1' {
f[i][j] = min(min(f[i - 1][j - 1], f[i - 1][j]), f[i][j - 1]) + 1
len = max(len, f[i][j])
}
}
}
return len * len
}
// 时间复杂度:O(logn * logn) 空间复杂度:O(logn)
func countNodes(root *TreeNode) int {
if root == nil {
return 0
}
x, y, l, r := 1, 1, root.Left, root.Right
for l != nil {
l = l.Left
x ++
}
for r != nil {
r = r.Right
y ++
}
if x == y {
return (1 << x) - 1
}
return countNodes(root.Left) + 1 + countNodes(root.Right)
}
// 时间复杂度:O(logn * logn) 空间复杂度:O(1)
func check(root *TreeNode, h, k int) bool {
bits := 1 << (h - 1)
for root != nil && bits != 0 {
if bits & k != 0 {
root = root.Right
} else {
root = root.Left
}
bits >>= 1
}
return root != nil
}
func countNodes(root *TreeNode) int {
if root == nil {
return 0
}
h, t := 0, root
for t.Left != nil {
h ++
t = t.Left
}
if h == 0 {
return 1
}
l, r := 1 << h, (1 << (h + 1)) - 1
for l < r {
mid := (l + r + 1) >> 1
if check(root, h, mid) {
l = mid
} else {
r = mid - 1
}
}
return l
}
func computeArea(ax1 int, ay1 int, ax2 int, ay2 int, bx1 int, by1 int, bx2 int, by2 int) int {
x := max(0, min(ax2, bx2) - max(ax1, bx1))
y := max(0, min(ay2, by2) - max(ay1, by1))
return (ax2 - ax1) * (ay2 - ay1) + (bx2 - bx1) * (by2 - by1) - x * y
}
class Solution {
public:
stack nums; // 操作数栈
stack op; // 操作符栈 保存 ( + - * / 注意右括号)是不会入栈的
unordered_map pr = { // 操作符的优先级
{'(', 0}, {'+', 1}, {'-', 1}, {'*', 2}, {'/', 2}
};
void eval() {
int b = nums.top(); nums.pop();
int a = nums.top(); nums.pop();
char c = op.top(); op.pop();
if (c == '+') a += b;
else if (c == '-') a -= b;
else if (c == '*') a *= b;
else if (c == '/') a /= b;
nums.push(a);
}
int calculate(string str) {
string s;
for (auto &c : str) // 先去除空格
if (c != ' ')
s += c;
for (int i = 0; i < s.size(); ++ i) {
char c = s[i];
if (isdigit(c)) { // 数字
int j = i;
while (j < s.size() && isdigit(s[j])) ++ j;
int x = stoi(s.substr(i, j - i));
nums.push(x);
i = j - 1;
} else if (c == '(') { // 左括号
op.push(c);
} else if (c == ')') { // 右括号
while (!op.empty() && op.top() != '(') eval();
op.pop(); // 弹出左括号
} else { // 符号 比如 + - / *
// 这里很坑,注意细节!!!
// !i处理情况:"+5-6" 添加0,使其成为"0+5-6"这种形式,让+成为加法而不是正号
// s[i-1]=='('处理情况:""1-(-2)"" 添加0,使其成为"1-(0-2)",然-成为减法而不是负号
if (!i || s[i - 1] == '(') nums.push(0);
while (!op.empty() && pr[op.top()] >= pr[c]) eval();
op.push(c);
}
}
while (!op.empty()) eval();
return nums.top();
}
};
// 两个队列实现栈
type MyStack struct {
q, tmp []int
}
func Constructor() MyStack {
return MyStack{}
}
func (this *MyStack) Push(x int) {
this.q = append(this.q, x)
}
func (this *MyStack) Pop() int {
s := len(this.q)
for i := 1; i < s; i ++ {
this.tmp = append(this.tmp, this.q[0])
this.q = this.q[1:]
}
ans := this.q[0]
this.q = this.q[1:]
this.q, this.tmp = this.tmp, this.q
return ans
}
func (this *MyStack) Top() int {
return this.q[len(this.q) - 1]
}
func (this *MyStack) Empty() bool {
return len(this.q) == 0
}
// 一个队列实现栈
type MyStack struct {
q []int
}
func Constructor() MyStack {
return MyStack{}
}
func (this *MyStack) Push(x int) {
this.q = append(this.q, x)
}
func (this *MyStack) Pop() int {
s := len(this.q)
for i := 1; i < s; i ++ {
this.q = append(this.q, this.q[0])
this.q = this.q[1:]
}
ans := this.q[0]
this.q = this.q[1:]
return ans
}
func (this *MyStack) Top() int {
return this.q[len(this.q) - 1]
}
func (this *MyStack) Empty() bool {
return len(this.q) == 0
}
func invertTree(root *TreeNode) *TreeNode {
if root == nil {
return nil
}
root.Left, root.Right = root.Right, root.Left
invertTree(root.Left)
invertTree(root.Right)
return root
}
// LC224的弱化版,可以直接把LC224的题解交上去,下面给出针对这题的简易写法
class Solution {
public:
stack nums; // 操作数栈
stack op; // 操作符栈
unordered_map pr = {
{'(', 0}, {'+', 1}, {'-', 1}, {'*', 2}, {'/', 2}
};
void eval() {
int b = nums.top(); nums.pop();
int a = nums.top(); nums.pop();
char c = op.top(); op.pop();
if (c == '+') a += b;
else if (c == '-') a -= b;
else if (c == '*') a *= b;
else if (c == '/') a /= b;
nums.push(a);
}
int calculate(string str) {
string s;
for (auto &c : str)
if (c != ' ')
s += c;
for (int i = 0; i < s.size(); ++ i) {
char c = s[i];
if (isdigit(c)) { // 数字
int j = i, x = 0;
// 题目数据保证答案是一个 32-bit 整数,所以可以用x = x * 10 + (s[j ++ ] - '0');
while (j < s.size() && isdigit(s[j])) x = x * 10 + (s[j ++ ] - '0');
nums.push(x);
i = j - 1;
} else { // 操作符 + - * /
while (!op.empty() && pr[op.top()] >= pr[c]) eval();
op.push(c); // 操作符入栈op
}
}
while (!op.empty()) eval();
return nums.top();
}
};
func summaryRanges(nums []int) []string {
n := len(nums)
ans := []string{}
for i := 0; i < n; i ++ {
j := i + 1
for j < n && nums[j] - nums[j - 1] == 1 {
j ++
}
if j - i == 1 {
ans = append(ans, strconv.Itoa(nums[i]))
} else {
ans = append(ans, strconv.Itoa(nums[i]) + "->" + strconv.Itoa(nums[j - 1]))
}
i = j - 1
}
return ans
}
func majorityElement(nums []int) []int {
p1, p2, c1, c2, n := 0, 0, 0, 0, len(nums)
for _, x := range nums {
if c1 != 0 && p1 == x {
c1 ++
} else if c2 != 0 && p2 == x {
c2 ++
} else if c1 == 0 {
p1 = x
c1 ++
} else if c2 == 0 {
p2 = x
c2 ++
} else {
c1 --
c2 --
}
}
c1, c2 = 0, 0
for _, x := range nums {
if x == p1 {
c1 ++
} else if x == p2 {
c2 ++
}
}
ans := []int{}
if c1 > n / 3 {
ans = append(ans, p1)
}
if c2 > n / 3 {
ans = append(ans, p2)
}
return ans
}
// 这里给出一种通用扩展解法:给定一个大小为 n 的整数数组,找出其中所有出现超过 ⌊ n/k ⌋ 次的元素。
class Solution {
public:
vector nums, ans;
int n;
void solve(int k) {
// 使用一个unordered_map来映射每个候选人及其计数。
unordered_map mp; // key:候选人 value:该候选人的出现次数
// 抵消阶段:遍历数组,更新或者抵消候选人的计数。
for (auto &x : nums) {
if (mp.count(x)) { // 如果x已经是候选人,则增加计数
++ mp[x];
} else if (mp.size() < k - 1) { // 如果x不是候选人,但候选人名额未满,则添加候选人
mp[x] = 1;
} else { // 如果不是候选人且候选人名额已满,则抵消所有候选人计数
for (auto it = mp.begin(); it != mp.end(); ) {
if (-- (it->second) == 0) {
it = mp.erase(it);
} else {
++ it;
}
}
}
}
// 计数阶段:重新计算每个候选人的计数以验证是否满足超过n/k的条件。
for (auto &it : mp) {
it.second = 0; // 重置计数
}
for (auto &x : nums) {
if (mp.count(x)) {
++ mp[x];
}
}
// 收集结果:返回满足条件的所有候选人。
for (auto &it : mp) {
if (it.second > n / k) {
ans.push_back(it.first);
}
}
}
vector majorityElement(vector& nums) {
this->nums = nums;
this-> n = nums.size();
solve(3);
return ans;
}
};
var k, ans int
func dfs(root *TreeNode) {
if root == nil {
return
}
dfs(root.Left)
k --
if k == 0 {
ans = root.Val
return
}
dfs(root.Right)
}
func kthSmallest(root *TreeNode, _k int) int {
k = _k
dfs(root)
return ans
}
func isPowerOfTwo(n int) bool {
// return n > 0 && (n & (-n) == n)
return n > 0 && (n & (n - 1) == 0)
}
type MyQueue struct {
a, b []int
}
func Constructor() MyQueue {
return MyQueue{}
}
func (this *MyQueue) solve() {
for len(this.a) > 0 {
n := len(this.a)
this.b = append(this.b, this.a[n - 1])
this.a = this.a[ : n - 1]
}
}
func (this *MyQueue) Push(x int) {
this.a = append(this.a, x)
}
func (this *MyQueue) Pop() int {
if len(this.b) == 0 {
this.solve()
}
n := len(this.b)
x := this.b[n - 1]
this.b = this.b[ : n - 1]
return x
}
func (this *MyQueue) Peek() int {
if len(this.b) == 0 {
this.solve()
}
return this.b[len(this.b) - 1]
}
func (this *MyQueue) Empty() bool {
return len(this.a) == 0 && len(this.b) == 0
}
class Solution {
public:
int solve(int n) {
string s = to_string(n);
int m = s.size(), f[m][m];
memset(f, -1 ,sizeof f);
function dfs = [&](int i, int cnt, bool isLimit) -> int {
if (i == m) return cnt;
if (!isLimit && ~f[i][cnt]) return f[i][cnt];
int up = isLimit ? s[i] - '0' : 9, ans = 0;
for (int d = 0; d <= up; ++ d) {
ans += dfs(i + 1, cnt + (d == 1), isLimit && d == up);
}
if (!isLimit) f[i][cnt] = ans;
return ans;
};
return dfs(0, 0, true);
}
int countDigitOne(int n) {
return solve(n);
}
};
func isPalindrome(head *ListNode) bool {
if head == nil || head.Next == nil {
return true
}
ppre, pre, slow, fast := (*ListNode)(nil), head, head, head
for fast != nil && fast.Next != nil {
pre = slow
slow = slow.Next
fast = fast.Next.Next
pre.Next = ppre
ppre = pre
}
if fast != nil {
slow = slow.Next
}
for pre != nil && slow != nil {
if pre.Val != slow.Val {
return false
}
pre, slow = pre.Next, slow.Next
}
return true
}
func lowestCommonAncestor(root, p, q *TreeNode) *TreeNode {
ancestor := root
for {
if p.Val < ancestor.Val && q.Val < ancestor.Val {
ancestor = ancestor.Left
} else if p.Val > ancestor.Val && q.Val > ancestor.Val {
ancestor = ancestor.Right
} else {
break
}
}
return ancestor
}
func getPath(root, target *TreeNode) []*TreeNode{
path := []*TreeNode{}
for root != target {
path = append(path, root)
if target.Val < root.Val {
root = root.Left
} else {
root = root.Right
}
}
path = append(path, target)
return path
}
func lowestCommonAncestor(root, p, q *TreeNode) *TreeNode {
path_p, path_q := getPath(root, p), getPath(root, q)
n := min(len(path_p), len(path_q))
for i := n - 1; i >= 0; i -- {
if path_p[i] == path_q[i] {
return path_p[i]
}
}
return nil
}
func dfs(root, target *TreeNode, path *[]*TreeNode) bool {
if root == nil {
return false
}
*path = append(*path, root)
if root == target {
return true
}
if dfs(root.Left, target, path) || dfs(root.Right, target, path) {
return true
}
*path = (*path)[:len(*path) - 1]
return false
}
func lowestCommonAncestor(root, p, q *TreeNode) *TreeNode {
var path_p, path_q []*TreeNode
dfs(root, p, &path_p)
dfs(root, q, &path_q)
n := min(len(path_p), len(path_q))
for i := n - 1; i >= 0; i -- {
if path_p[i] == path_q[i] {
return path_p[i]
}
}
return nil
}
func dfs(root, target *TreeNode, path *[]*TreeNode) bool {
if root == nil {
return false
}
if root == target {
*path = append(*path, target)
return true
}
if dfs(root.Left, target, path) || dfs(root.Right, target, path) {
*path = append(*path, root)
return true
}
return false
}
func reverse(path []*TreeNode) {
for i, j := 0, len(path) - 1; i < j; i, j = i + 1, j - 1 {
path[i], path[j] = path[j], path[i]
}
}
func lowestCommonAncestor(root, p, q *TreeNode) *TreeNode {
var path_p, path_q []*TreeNode
dfs(root, p, &path_p)
dfs(root, q, &path_q)
reverse(path_p)
reverse(path_q)
n := min(len(path_p), len(path_q))
for i := n - 1; i >= 0; i -- {
if path_p[i] == path_q[i] {
return path_p[i]
}
}
return nil
}
func lowestCommonAncestor(root, p, q *TreeNode) *TreeNode {
if root == nil || root == p || root == q {
return root
}
left := lowestCommonAncestor(root.Left, p, q)
right := lowestCommonAncestor(root.Right, p, q)
if left == nil {
return right
}
if right == nil {
return left
}
return root
}
func dfs(root, target *TreeNode, path *[]*TreeNode) bool {
if root == nil {
return false
}
*path = append(*path, root)
if root == target {
return true
}
if dfs(root.Left, target, path) || dfs(root.Right, target, path) {
return true
}
*path = (*path)[:len(*path) - 1]
return false
}
func lowestCommonAncestor(root, p, q *TreeNode) *TreeNode {
var path_p, path_q []*TreeNode
dfs(root, p, &path_p)
dfs(root, q, &path_q)
n := min(len(path_p), len(path_q))
for i := n - 1; i >= 0; i -- {
if path_p[i] == path_q[i] {
return path_p[i]
}
}
return nil
}
func dfs(root, target *TreeNode, path *[]*TreeNode) bool {
if root == nil {
return false
}
if root == target {
*path = append(*path, target)
return true
}
if dfs(root.Left, target, path) || dfs(root.Right, target, path) {
*path = append(*path, root)
return true
}
return false
}
func reverse(path []*TreeNode) {
for i, j := 0, len(path) - 1; i < j; i, j = i + 1, j - 1 {
path[i], path[j] = path[j], path[i]
}
}
func lowestCommonAncestor(root, p, q *TreeNode) *TreeNode {
var path_p, path_q []*TreeNode
dfs(root, p, &path_p)
dfs(root, q, &path_q)
reverse(path_p)
reverse(path_q)
n := min(len(path_p), len(path_q))
for i := n - 1; i >= 0; i -- {
if path_p[i] == path_q[i] {
return path_p[i]
}
}
return nil
}
func deleteNode(node *ListNode) {
node.Val = node.Next.Val
node.Next = node.Next.Next
}
// 时间复杂度:O(n) 空间复杂度:O(n) 因为开了L,R这两个额外数组
func productExceptSelf(nums []int) []int {
n := len(nums)
L, R, ans := make([]int, n), make([]int, n), make([]int, n)
L[0] = 1
for i := 1; i < n; i ++ {
L[i] = L[i - 1] * nums[i - 1]
}
R[n - 1] = 1
for i := n - 2; i >= 0; i -- {
R[i] = R[i + 1] * nums[i + 1]
}
for i := 0; i < n; i ++ {
ans[i] = L[i] * R[i]
}
return ans
}
// 时间复杂度:O(n) 空间复杂度:O(1) 省去了L、R两个数组的空间
func productExceptSelf(nums []int) []int {
n := len(nums)
ans := make([]int, n)
ans[0] = 1
for i := 1; i < n; i ++ {
ans[i] = ans[i - 1] * nums[i - 1]
}
R := 1
for i := n - 1; i >= 0; i -- {
ans[i] *= R
R *= nums[i]
}
return ans
}
func maxSlidingWindow(nums []int, k int) []int {
n := len(nums)
q := make([]int, n)
ans := []int{}
hh, tt := 0, -1
for i := 0; i < n; i ++ {
if hh <= tt && q[hh] < i - k + 1 {
hh ++
}
for hh <= tt && nums[i] >= nums[q[tt]] {
tt --
}
tt ++
q[tt] = i
if i >= k - 1 {
ans = append(ans, nums[q[hh]])
}
}
return ans
}
func searchMatrix(g [][]int, target int) bool {
n, m := len(g), len(g[0])
if n == 0 || m == 0 {
return false
}
for i := 0; i < n; i ++ {
l, r := 0, m - 1
for l < r {
mid := (l + r + 1) >> 1
if g[i][mid] <= target {
l = mid
} else {
r = mid - 1
}
}
if g[i][l] == target {
return true
}
}
return false
}
func searchMatrix(g [][]int, target int) bool {
n, m := len(g), len(g[0])
if n == 0 || m == 0 {
return false
}
x, y := 0, m - 1
for x < n && y >= 0 {
if g[x][y] > target {
y --
} else if g[x][y] < target {
x ++
} else {
return true
}
}
return false
}
var s string
func dfs(l, r int) []int {
if l > r {
return []int{}
}
var ans []int
isNum := true
for i := l; i <= r; i ++ {
if !unicode.IsDigit(rune(s[i])) {
isNum = false
break
}
}
if isNum {
num, _ := strconv.Atoi(s[l : r + 1])
ans = append(ans, num)
return ans
}
for i := l; i <= r; i ++ {
if s[i] == '+' || s[i] == '-' || s[i] == '*' {
left := dfs(l, i - 1)
right := dfs(i + 1, r)
for _, a := range left {
for _, b := range right {
x := 0
if s[i] == '+' {
x = a + b
} else if s[i] == '-' {
x = a - b
} else if s[i] == '*' {
x = a * b
}
ans = append(ans, x)
}
}
}
}
return ans
}
func diffWaysToCompute(expression string) []int {
s = expression
return dfs(0, len(s) - 1)
}
func isAnagram(s, t string) bool {
if len(s) != len(t) {
return false
}
mp := make(map[rune]int)
for _, c := range s {
mp[c] ++
}
for _, c := range t {
mp[c] --
if mp[c] < 0 {
return false
}
}
return true
}
var ans []string
func dfs(root *TreeNode, path string) {
if root == nil {
return
}
path += strconv.Itoa(root.Val)
if root.Left == nil && root.Right == nil {
ans = append(ans, path)
return
}
if root.Left != nil {
dfs(root.Left, path + "->")
}
if root.Right != nil {
dfs(root.Right, path + "->")
}
}
func binaryTreePaths(root *TreeNode) []string {
if root == nil {
return nil
}
ans = []string{}
dfs(root, "")
return ans
}
func addDigits(n int) int {
if n == 0 {
return 0
}
if n % 9 != 0 {
return n % 9
}
return 9
}
func singleNumber(nums []int) []int {
sum := 0
for _, x := range nums {
sum ^= x
}
var pos int
for i := 0; i < 32; i ++ {
if (sum >> i) & 1 == 1 {
pos = i
break
}
}
s0, s1 := 0, 0
for _, x := range nums {
if (x >> pos) & 1 == 1 {
s1 ^= x
} else {
s0 ^= x
}
}
return []int{s0, s1}
}
func isUgly(n int) bool {
if n <= 0 {
return false
}
for n % 2 == 0 {
n /= 2
}
for n % 3 == 0 {
n /= 3
}
for n % 5 == 0 {
n /= 5
}
return n == 1
}
func nthUglyNumber(n int) int {
f := make([]int, n + 1)
f[1] = 1
p2, p3, p5 := 1, 1, 1
for i := 2; i <= n; i ++ {
t := min(min(2 * f[p2], 3 * f[p3]), 5 * f[p5])
f[i] = t
if t == 2 * f[p2] {
p2 ++
}
if t == 3 * f[p3] {
p3 ++
}
if t == 5 * f[p5] {
p5 ++
}
}
return f[n]
}
func missingNumber(nums []int) int {
ans, n := 0, len(nums)
for _, x := range nums {
ans ^= x
}
for i := 0; i <= n; i ++ {
ans ^= i
}
return ans
}
class Solution {
public:
int missingNumber(vector<int>& nums) {
int s = 0, n = nums.size(), tot = n * (n + 1) / 2;
for (auto &x : nums) s += x;
return tot - s;
}
};
class Solution {
public:
string num0_19[20] = {
"Zero", "One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", "Ten",
"Eleven", "Twelve", "Thirteen", "Fourteen", "Fifteen", "Sixteen", "Seventeen", "Eighteen", "Nineteen"
};
string num20_90[10] = {
"", "", "Twenty", "Thirty", "Forty", "Fifty", "Sixty", "Seventy", "Eighty", "Ninety"
};
string num2str_large [4] = {
"Billion", "Million", "Thousand", ""
};
string get(int x) { // 返回1~999的英文表示
string ans = "";
if (x >= 100) {
ans += num0_19[x / 100] + " Hundred ";
x %= 100;
}
if (x >= 20) {
ans += num20_90[x / 10] + " ";
x %= 10;
}
if (x != 0) ans += num0_19[x] + " ";
return ans;
}
string numberToWords(int num) {
if (!num) return num0_19[0];
string ans = "";
for (int i = 1e9, j = 0; i >= 1; i /= 1000, ++ j) {
if (num >= i) {
ans += get(num / i) + num2str_large [j] + " ";
num %= i;
}
}
// 去掉末尾多余的空格
while (ans.back() == ' ') ans.pop_back();
return ans;
}
};
// 时间复杂度:O(nlogn) 空间复杂度:O(1)
var c []int
func check(h int) bool{
cnt := 0
for _, x := range c {
if x >= h {
cnt ++
}
if cnt >= h {
return true
}
}
return false
}
func hIndex(citations []int) int {
c = citations
n := len(c)
l, r := 0, n
for l < r {
mid := (l + r + 1) >> 1
if check(mid) {
l = mid
} else {
r = mid - 1
}
}
return l
}
// 时间复杂度:O(n) 空间复杂度:O(n)
func hIndex(c []int) int {
tot, n := 0, len(c)
cnt := make([]int, n + 1)
for i := 0; i < n; i ++ {
if c[i] >= n {
cnt[n] ++
} else {
cnt[c[i]] ++
}
}
for i := n; i >= 0; i -- {
tot += cnt[i]
if tot >= i {
return i
}
}
return 0
}
func hIndex(c []int) int {
n := len(c)
l, r := 0, n
for l < r {
mid := (l + r + 1) >> 1
if c[n - mid] >= mid {
l = mid
} else {
r = mid - 1
}
}
return l
}
func firstBadVersion(n int) int {
l, r := 1, n
for l < r {
mid := (l + r) >> 1
if isBadVersion(mid) {
r = mid
} else {
l = mid + 1
}
}
return l
}
func numSquares(m int) int {
var v []int
n := 0
v = append(v, 0)
for i := 1; i <= int(math.Sqrt(float64(m))); i ++ {
v = append(v, i * i)
n++
}
f := make([]int, m + 1)
for i := range f {
f[i] = 0x3f3f3f3f
}
f[0] = 0
for i := 1; i <= n; i ++ {
for j := v[i]; j <= m; j ++ {
f[j] = min(f[j], f[j - v[i]] + 1)
}
}
return f[m]
}
class Solution {
public:
using LL = long long;
vector ans;
string path, s;
void dfs(int u, int len, LL a, LL b, LL target) {
if (u == s.size()) {
// 最后是 a + 1 * () len减去1是因为要减掉我们在后面添加的+号
if (a == target) ans.push_back(path.substr(0, len - 1));
return;
}
LL c = 0;
for (int i = u; i < s.size(); ++ i) {
// 去掉前导0
if (i > u && s[u] == '0') break;
c = c * 10 + s[i] - '0';
path[len ++ ] = s[i];
path[len] = '+';
dfs(i + 1, len + 1, a + b * c, 1, target);
if (i + 1 < s.size()) {
path[len] = '-';
dfs(i + 1, len + 1, a + b * c, -1, target);
}
if (i + 1 < s.size()) {
path[len] = '*';
dfs(i + 1, len + 1, a, b * c, target);
}
}
}
vector addOperators(string num, int target) {
this->s = num;
path.resize(100);
dfs(0, 0, 0, 1, target);
return ans;
}
};
func moveZeroes(nums []int) {
k, n := 0, len(nums)
for _, x := range nums {
if x != 0 {
nums[k] = x
k ++
}
}
for k < n {
nums[k] = 0
k ++
}
}
class PeekingIterator : public Iterator {
public:
int cur;
bool ok;
PeekingIterator(const vector& nums) : Iterator(nums) {
ok = Iterator::hasNext();
if (ok) cur = Iterator::next();
}
int peek() {
return cur;
}
int next() {
int t = cur;
ok = Iterator::hasNext();
if (ok) cur = Iterator::next();
return t;
}
bool hasNext() const {
return ok;
}
};
// 二分答案 时间复杂度:O(nlogn) 空间复杂度:O(1)
func findDuplicate(nums []int) int {
l, r := 1, len(nums) - 1 // 二分答案区间[1, len(nums)-1]
for l < r {
cnt, mid := 0, (l + r) >> 1
for _, x := range nums {
if x >= l && x <= mid {
cnt ++
}
}
if cnt > mid - l + 1 {
r = mid
} else {
l = mid + 1
}
}
return l
}
// 快慢指针 时间复杂度:O(n) 空间复杂度:O(1)
func findDuplicate(nums []int) int {
slow, fast := 0, 0
for {
slow = nums[slow]
fast = nums[nums[fast]]
if slow == fast {
break
}
}
slow = 0
for slow != fast {
slow = nums[slow]
fast = nums[fast]
}
return slow
}
func gameOfLife(g [][]int) {
n, m := len(g), len(g[0])
if n == 0 || m == 0 {
return
}
dx := []int{-1, -1, -1, 0, 0, 1, 1, 1}
dy := []int{-1, 0, 1, -1, 1, -1, 0, 1}
for i := 0; i < n; i ++ {
for j := 0; j < m; j ++ {
cnt := 0
for k := 0; k < 8; k ++ {
a, b := i + dx[k], j + dy[k]
if a >= 0 && a < n && b >= 0 && b < m {
if g[a][b] & 1 == 1 {
cnt ++
}
}
}
if g[i][j] == 1 {
if cnt < 2 || cnt > 3 {
g[i][j] = 1
} else {
g[i][j] = 3
}
} else {
if cnt == 3 {
g[i][j] = 2
} else {
g[i][j] = 0
}
}
}
}
for i := 0; i < n; i ++ {
for j := 0; j < m; j ++ {
g[i][j] >>= 1
}
}
}
class Solution {
public:
bool wordPattern(string pattern, string s) {
stringstream ss(s);
vector words;
string w;
while (ss >> w ) words.push_back(w);
if (words.size() != pattern.size() ) return false;
unordered_map PS;
unordered_map SP;
for (int i = 0; i < words.size(); ++ i) {
char x = pattern[i];
string y = words[i];
if ((PS.count(x) && PS[x] != y) || (SP.count(y) && SP[y] != x)) return false;
PS[x] = y, SP[y] = x;
}
return true;
}
};
func canWinNim(n int) bool {
return n & 3 != 0
// return n % 4 != 0
}
class MedianFinder {
public:
priority_queue a; // 大根堆
priority_queue, greater> b; // 小根堆
MedianFinder() {}
void addNum(int x) {
if (a.empty() || x <= a.top()) {
a.push(x);
if (a.size() > b.size() + 1) {
b.push(a.top());
a.pop();
}
} else {
b.push(x);
if (b.size() > a.size()) {
a.push(b.top());
b.pop();
}
}
}
double findMedian() {
if ((a.size() + b.size()) & 1) return a.top();
return (a.top() + b.top()) / 2.0;
}
};
class Codec {
public:
void dfs_s(TreeNode* root, string &s) { // 序列化
if (!root) {
s += '#';
return ;
}
s += to_string(root->val) + '!';
dfs_s(root->left, s);
dfs_s(root->right, s);
}
// Encodes a tree to a single string.
string serialize(TreeNode* root) {
string s;
dfs_s(root, s);
return s;
}
// Decodes your encoded data to tree.
TreeNode* deserialize(string data) {
if (data == "#") return nullptr;
int i = 0;
return dfs_d(data, i);
}
TreeNode* dfs_d(string &s, int &i) { // 反序列化
if (s[i] == '#') {
++ i;
return nullptr;
}
int k = i;
while (i < s.size() && s[i] != '!') ++ i;
auto root = new TreeNode(stoi(s.substr(k, i - k)));
if (i == s.size()) return root;
else ++ i;
root->left = dfs_d(s, i);
root->right = dfs_d(s, i);
return root;
}
};
func getHint(secret string, guess string) string {
mp := make(map[byte]int)
tot := 0
for _, c := range secret {
mp[byte(c)] ++
}
for _, c := range guess {
if mp[byte(c)] > 0 {
mp[byte(c)] --
tot ++
}
}
bulls := 0
for i := 0; i < len(secret); i ++ {
if secret[i] == guess[i] {
bulls ++
}
}
return fmt.Sprintf("%dA%dB", bulls, tot - bulls)
}
func lengthOfLIS(nums []int) int {
d := []int{}
for _, x := range nums {
if len(d) == 0 || x > d[len(d) - 1] {
d = append(d, x)
} else if x == d[len(d) - 1] {
continue
} else {
l, r := 0, len(d) - 1
for l < r {
mid := (l + r) >> 1
if d[mid] >= x {
r = mid
} else {
l = mid + 1
}
}
d[l] = x
}
}
return len(d)
}