《剑指offer》个人总结

基础知识:编程语言、数据结构、算法

一、赋值运算符函数

  1. 返回值类型声明为引用,并返回 *this,只有返回引用才可以连续赋值。
  2. 传入参数类型声明为常量引用,避免调用复制构造函数和传入实例。
  3. 判断传入参数与当前实例 *this 是否相同。
  4. 释放自身已有内存再分配,避免内存泄漏。
  5. 在4基础上,为避免释放后分配失败,可以先分配再释放,或者先创建临时实例再交换。

二、实现Singleton模式

public sealed class Singleton {
	private Singleton() {}
	private static object syncObj = new object();
	private static Singleton instance = null;
	public static Singleton Instance {
		get {
			if (instance == null) { // 避免每次调用加锁耗时
				lock(syncObj) { // 避免多线程同时调用
					if (instance == null) // 不存在则创建
						instance = new Singleton();
				}
			}
			return instance;
		}
	}
}

三、数组中重复的数字

  1. 找出数组中重复的数字(数组大小为n,其元素为0~n-1)
  2. 不修改数组找(数组大小为n+1,其元素为1~n)
    解:二分查找统计法O(nlogn)

四、二维数组中的查找

  1. 从左到右递增,从上到下递增
    解:找右上角,根据大小关系减列或加行

五、替换空格

  1. 将字符串中空格替换成%20
    解:先遍历确定空格数量,再反向逐一赋值

六、从尾到头打印链表

解:a.反转链表 b.栈 c. 递归

七、重建二叉树

  1. 输入前序和中序遍历,重建二叉树

八、二叉树的下一个节点

  1. 给定二叉树和其中之一节点,找出中序遍历序列的下一个节点(含父节点指针)
    解:分类讨论(有无右子节点,是否是父节点的左节点等)

九、用两个栈实现队列

十、斐波那契数列

  1. 求第n项
  2. 青蛙跳台阶(一次跳1或2级,到第n级共有多少种跳法)
    解:等于斐波那契

十一、旋转数组的最小数字

  1. 把数组最开始若干元素移到末尾即为旋转,输入递增排序的一个旋转,输出旋转数组的最小元素。
    解:二分查找,比较左右中元素大小关系判断最小元素位置,特殊情况是若全部相同则只能顺序查找

十二、矩阵中的路径

  1. 判断矩阵是否存在一条包含某字符串所有字符的路径,不能经过重复元素。
    解:回溯法

十三、机器人的运动范围

十四、剪绳子

  1. 把长为n的绳子剪成m段,每段长最大乘积可能是多少?
    解:a.动规(从上而下分析问题,从下而上解决问题) b.贪心(数学)

十五、二进制中1的个数

解:a.右移判断最右位(负数会引起死循环) b.将1左移逐个对比 (循环位数次数)c.减1取与(循环1的次数)


高质量代码:规范性、完整性、鲁棒性

十六、数值的整数次方

  1. double Power(double base, int exponent)
    解:注意特殊情况正负0

十七、打印从1到最大的n位数

解:a.字符串模拟数字加法 b.全排列递归

十八、删除链表的节点

  1. 给定单向链表头指针和一个节点指针,在O(1)时间内删除该节点
    解:复制下个节点信息,包括3种特殊情况 a.只有一个节点 b.非尾节点 c.尾节点
  2. 删除排序链表中重复的节点
    解:头节点可能被删除,函数声明应为ListNode **pHead

十九、正则表达式匹配

  1. 实现可匹配包含’.‘和’*'的正则表达式函数。
    解:状态机

二十、表示数值的字符串

  1. 判断字符串是否表示数值(包括整数和小数),如+100、5e2、-123、3.1416、-1E-16等,但12e、1a3.14、1.2.3、±5、12e+5.4等都不是。
    在这里插入图片描述

二十一、调整数组顺序使奇数位于偶数前面

解:需考虑可扩展解法,函数指针

二十二、链表中倒数第k个节点

解:特殊情况,不足k个或空指针等

二十三、链表中环的入口节点

二十四、反转链表

二十五、合并两个排序的链表

解:递归

二十六、树的子结构


思路:画图、举例、分解

二十七、二叉树的镜像

二十八、对称的二叉树

二十九、顺时针打印矩阵

三十、包含min函数的栈

  1. 实现调用min、push、pop时间复杂度均为O(1)的栈类
    解:设立额外辅助栈,每次push min(辅助栈顶,新元素)

三十一、栈的压入、弹出序列

三十二、从上到下打印二叉树

  1. 不分行从上到下从左到右打印
  2. 分行从上到下从左到右打印
  3. 之字形打印

解:12用队列,3用两个栈

三十三、二叉搜索树的后序遍历序列

三十四、二叉树中和为某一值的路径

三十五、复杂链表的复制

解:在原链表每个节点后面复制一个新节点

三十六、二叉搜索树与双向链表

  1. 将二叉搜索树转成一个排序的双向链表,要求不能创建新节点,只能调整原节点指针方向
    在这里插入图片描述

三十七、序列化二叉树

三十八、字符串的排列

解:交换、递归、交换


效率:时间与空间的平衡

三十九、数组中出现次数超过一半的数字

解:a.二分法排序,直到找到中位数,时间复杂度O(n) b.遍历记录当前数和频率,当下一个数不相同时减频率,否则加,当次数为0则重设当前数。

四十、最小的k个数

解:a.二分法排序,直到找到第k位,时间复杂度O(n) b.最大堆,红黑树,时间复杂度O(nlogk)

四十一、数据流中的中位数
在这里插入图片描述
四十二、连续子数组的最大和

四十三、1~n整数中1出现的次数

在这里插入图片描述
四十四、数字序列中某一位的数字

四十五、把数组排成最小的数

四十六、把数字翻译成字符串

解:从右往左

四十七、礼物的最大价值

解:二维数组可优化成一维数组

四十八、最长不含重复字符的子字符串

四十九、丑数

  1. 只包含因子2、3和5的数称为丑数,求按从小到大顺序的第n个丑数在这里插入图片描述

五十、第一个只出现一次的字符

五十一、数组中的逆序对

解:归并排序,时间复杂度O(nlogn),空间复杂度O(n)

五十二、两个链表的第一个公共节点


能力:知识迁移

五十三、在排序数组中查找数字

  1. 数字k在排序数组中出现的次数
    解:二分法找第一个k和最后一个k,时间复杂度O(logn)
  2. 0~n-1中缺失的数字
  3. 找到单调递增且元素唯一的数组中,与下标值相等的元素

五十四、二叉搜索树的第k大节点

解:中序遍历

五十五、二叉树的深度

  1. 求二叉树深度,即最长路径长度
  2. 判断是否是平衡二叉树

五十六、数组中数字出现的次数

  1. 一个整型数组中除两个只出现一次的数字外,其他数字都出现了两次,找到这两个数,时间复杂度要求O(n),空间复杂度要求O(1)
    解:逐个异或,按异或结果某一位是否为1划分两组,再在每个组求异或
  2. 一个数组中除一个只出现一次的数字外,其他数字都出现了三次,找到那个数
    解:逐个记录每位相加,找到所有不能被3整除的位结果,即表示只出现一次的数

五十七、和位s的数字

  1. 输入递增数组和数字s,找到和为s的任意一对数
    解:双指针
  2. 所有和为s的连续正数序列

五十八、翻转字符串

  1. 翻转句中单词顺序,单词内字符顺序不变,标点符号与普通字母相同处理
    解:两次翻转:先翻转所有字符,再翻转单词
  2. 左旋转字符串

五十九、队列的最大值

  1. 滑动窗口的最大值
  2. 定义一个队列并实现函数max得到最大值,要求max,push_back,pop_front时间复杂度都是O(1)

六十、n个骰子的点数

六十一、扑克牌中的顺子

六十二、圆圈中最后剩下的数字

六十三、股票的最大利润

六十四、求1+2+…+n

  1. 要求不能使用乘除法、for、while、if、else、switch、case等关键字及条件判断语句(A?B:C)
    解:a.定义n维指针数组,指向使用构造函数++且用static求和的自定义类 b.定义长度为2的指针数组,!!n,虚函数,递归n-1 c.函数指针 d.模板类型

六十五、不用加减乘除做加法

int Add(int num1, int num2) {
    while (num2 != 0) {
        int sum = num1 ^ num2; 
        int carry = (num1 & num2) << 1; 
        num1 = sum;
        num2 = carry;
    }
    return num1;
}

六十六、构建乘积数组


其他知识点

  1. sizeof(空类型、+构造&析构、+虚函数)
  2. sizeof(数组、指针、数组退化指针)
  3. 拷贝构造函数传址
  4. struct和class区别,c#对应区别
  5. c#调用顺序:静态构造函数、静态变量、成员变量、构造函数
  6. 字符串末尾还含有’\0’字符
char s1[] = "hello"; char s2[] = "hello"; // s1 != s2,数组初始地址不同
char *s3 = "hello"; char *s4 = "hello"; // s3 == s4,指针指向同一常量字符串地址
  1. 3种错误处理方式:返回值、全局变量和异常
  2. 判断浮点数是否相等不能直接==,应判断是否相差小于设定阈值
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值