题目 思路 备注
    打乱数组 shuffle时,copy一个新数组,迭代并随机交换 copy = nums.clone(); j = random(len); copy[i] <->copy[j]
    最小栈 包装原节点: val -> [val, min], 每个节点都记着当前最小值 每次入栈时维护更新最小值
    Fizz Buzz 依次对15、3、5取模:
    模值为0时即可分别得到FizzBuzz, Fizz, Buzz
    计算质数 遍历 [2, n-1],对于此区间内x而言,k*x (kx<n)一定不是质数 for (inti = 2; i < n; i++) {
    if (notPrime[i]) continue;//非质数
    cnt++; //质数个数累加
    for (intj = i; j < n; j += i) notPrime[j] = true; //排除非质数
    }
    3的幂 n不断除3,都能整除,且余数为0,最终能得到1即可 public boolean isPowerOfThree(int n) {
    if(n<=1 || n%3 !=0 ) return n==1;
    return isPowerOfThree(n/3);
    }
    罗马数字转整数 枚举所有基本数字位(一个或两个字母),放入Map进行判断
    二叉树的序列化与反序列化 序列化:前序遍历,注意每个值序列化为:”${val},” , 且val可能为null
    反序列化:按”,”split,然后建根,再递归建左右子树
    常数时间插入、删除和随机获取元素 内部维护一个List和HashMap,在List中插入元素时,Map中维护该元素在List中的下标,以保证能O(1)删除。
    快乐数(数字各位平方和==1)
    1. 迭代(or递归)法
    1. 双指针法:想像一个从【n->…->1】的链表,如果能遍历到1(无环)表示是快乐数,否则不是。
    迭代法:image.png
    循环链表法:image.png
    阶乘后的0 尾随0的个数等于包含5的个数 image.png
    Excel列表序号 26进制数转十进制数 image.png
    Pow(x,n) 快速幂,原理: 数学与设计问题 - 图5, 考虑整数除法时,有:
    b为偶数时: 数学与设计问题 - 图6, b为奇数时: 数学与设计问题 - 图7
    image.png
    x的平方根 二分法,注意在取left下一轮值域时已经将当前mid存入结果了
    数学与设计问题 - 图9时,值域为:数学与设计问题 - 图10(mid本身已存到过res了)。 否则,值域为:数学与设计问题 - 图11
    image.png
    两数相除 将两数都转为负数,然后把除数不断往回加即可(相当于变相乘法)
    同时考虑以下边界问题:
    1. 数学与设计问题 - 图13(这是个溢出的整数,最大整数只能为数学与设计问题 - 图14)
    1. 数学与设计问题 - 图15
    image.png
    分数转小数 a/b有三种结果(先判断结果的正负):
    1. 整除时,结果为一个整数
    2. 不能整除时,整数部分直接得到,小数部分有限
    3. 不能整除时,整数部分直接得到,小数部分无限循环or不循环
    小技巧:统一转为long型正数,以方便处理; 使用一个Map保存循环计算过的小数,以防止无限循环
    image.png
    LRU缓存机制 一:使用LinkedHashMap可以直接实现
    二、HashMap辅以双向链表实现:
    - 双链表按使用顺序存储元素,头部是最新的,尾部是最旧的
    - HashMap通过缓存数据的键映射到其在双向链表中的位置


    - 访问时: 如果map中存在,则拿到其位置,然后在双链表中将其移到头部
    - 添加时:
    - 已存在:则移到头部
    - 不存在:
    - 添加到链表头部,同时加到Map中去
    - 如果超容量了,删掉尾部元素,同时从Map中删此元素
    实现前缀树 前缀树的常用结构, 比较简单,关注其insert和query方法即可
    image.pngimage.png
    前缀树插入操作: 前缀树查找操作:
    image.pngimage.png
    扁平化嵌套列表迭代器 维护一个扁平的List, 在对象实例化时,以dfs的方式将嵌套列表打平即可 image.png
    最大数 将数组重排序,以组成一个最大整数。 核心思路在于对字符串的比较:
    Collections.sort(list, (a,b)-> (b+a).compareTo(a+b));
    将数组元素全部转成String类型后,加入List,再按自然序倒序排列即可
    image.png
    直线上最多的点数
    image.png
    朴素解法:三层循环,前两层确定一条直线,第三层枚举经过此直线的点。
    - 1层循环: 数学与设计问题 - 图25, 点: 数学与设计问题 - 图26 , cnt=1
    - 2层循环: 数学与设计问题 - 图27, 点: 数学与设计问题 - 图28 , 与i的斜率:数学与设计问题 - 图29 , cnt=2
    - 3层循环: 数学与设计问题 - 图30, 点:数学与设计问题 - 图31,与i的斜率:数学与设计问题 - 图32, cnt++

    斜率相等时,三点一线: 数学与设计问题 - 图33 | image.png | | 天际线问题 | 此题的本意:求轮廓中的所有的水平线段的左端点(即「关键点」),并按顺序输出。可以采用画轮廓的思路。
    以下是核心思路——「关键点」出现在从垂直转水平的地方,而水平转垂直的地方无关键点,因此有垂直方向移动并产生高度差的地方,就会出现「关键点」。
    这里生产「关键点」按照↑方向还是↓方向, 可以分两种情况:
    情况 1:从↑转→,纵坐标最大的点是关键点;
    情况 2:从↓转→,纵坐标第二大的点是关键点。 | image.png | | 柱状图中矩形的最大面积

    image.png | 解法: 单调递增栈
    - 当柱子高度大于栈顶时,就将柱子依次入栈。 否则挨个出栈直至栈顶元素不大于当前要入栈的元素。
    - 在挨个出栈的过程中,每出栈一个元素,就计算一下以这个元素为中心能够向右扩展(只能向右,向左不会让面积更大)得到的最大矩形面积,然后更新结果的最大值即可。
    其中有个简化逻辑的小技巧: 给原数组左右都加一个高度为0的柱子,作为哨兵,以防止栈空 | image.png |