剑指offer总结

本文是年初找实习时做的总结,为方便理解,建议读者先自行撸一遍剑指offer

剑指offer刷题总结
  • 爬梯子,矩形覆盖(P10),实际上是斐波那契数列

  • 求前k大(P40),一半以上的数字(P39),中位数(P41),用快排

int Partition(vector<int> &nums, int start, int end)

{
    int smaller = start - 1;
    for (int i = start; i != end; ++i) {
        if (nums[i] < nums[end]) {
            ++smaller;
            Swap(&nums[i], &nums[smaller]);
        }
    }
    ++smaller;
    Swap(&nums[smaller], &nums[end]);
    return smaller;
}
  • 采用红黑树求前k大的数据,复杂度为O(nlgk),适合海量数据,STL中可用set和multiset

  • 和字符相关的,可用字符数组int ch[256],以空间换时间,如果只包含字母,则可初始化数组int ch[26],本质上是在O(1)的时间上查表。如第一次只出现一次的字符(P50),从第一个字符串中删除在第二个字符串中出现的字符,删除字符串中所有重复的字符,判断两个单词是否包含相同的字母等

  • 求最大最小值,考虑用动态规划,如连续最大子数组(P42),礼物的最大价值(P47)等,对于自顶向下递归的解法,会产生重复解,优化思路可采用动态规划,自底向上求。股票的最大利润(P63)可以转换为P42

  • 二叉树的题,大多可递归求解。

  • 二叉树经常和栈以及队列结合。如,若要宽度遍历,则结合队列,如换行打印二叉树(P32)、之字形打印二叉树;二叉树中和为某一值的路径(P34),采用了栈的思路

  • 栈和队列可相关转化。如用两个栈实现队列(P9)

  • 二叉树和链表可相互转化,如二叉搜索树与双向链表(P36),树中节点的最低公共祖先(P68)

  • 位运算异或去重,如找出数组中只出现一次的数字(P56);左右移位求目标值,如不用加减乘数做加法(P65),二进制中1的个数(P15)

  • 如果要用整数累加或累乘,可能会溢出,考虑用字符串/位运算/数组模拟大数的加减,如打印从1到最大的n位数(P17)

  • 所有带排序的数组,优先考虑用二分查找的思路,将复杂度降至O(lgn),如旋转数组的最小值(P11),在排序数组中查找数字(P54),0~n-1中缺失的数字,单调递增数组中数值和下标相等的元素

  • 很多采用一个指针遍历解题为 O(n^2) 的复杂度,但是改为两个指针时可降低复杂度至O(n)。如和为s的数字(P57),两个链表的第一个公共节点(P52),链表中倒数第k个节点(P22),调整数组顺序使奇数位于偶数前面(P21)

  • 约瑟夫(Josephuse)环,圆圈中最后剩下的数字(P62),一种解法是用STL中的list模拟环状链表,也可用公式:

for (int i = 2; i <= n; ++i)
    last = (last + m) % i;
  • 回溯法,递归求解,需要访问矩阵中的若干元素;需要维护一个visited数组以记录有哪些元素被访问过,避免重复计算。如八皇后,矩阵路径(P12),机器人的运动范围(P13)等
    回溯法的框架:
    在这里插入图片描述
注意事项
  • 在写核心代码前,首先对输入数据进行合法性检查,如输入数组为空,输入数据非法,输入数据溢出,是否有正负数限制,指针为空,字符串为空等情况;
  • 在写核心代码时,应检查是否会除0,是否会越界,会不会死循环,边界条件,递归的终止条件是否正确等
  • 进行完整、规范的代码测试,如传入空指针,空数组,空字符串,非法数据,边界数据以判断程序是否能正确处理
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值