1.大数运算
(整型或浮点型)大数加减乘除、阶乘
以下,都为人工竖式思路
加法:模拟人工竖式,标记进位
减法:先判断大的,模拟人工竖式,标记借位
乘法:模拟竖式,从低位向高位乘,再进行各位的加法及进位
除法:
取模:模拟人工竖式,被除数-除数的10^n的倍数,n即商的所在位
取余:如上
阶乘:
求阶乘位数:lg(N!) = [lg(N*(N-1)*(N-2)*...*3*2*1)]+1= [lgN+lg(N-1)+lg(N-2)+...+lg3+lg2+lg1]+1
求阶乘:进位,一个个相乘,a[]标记每一位的结果,若有进位,a[]数组对应位置相加
注意:
若为浮点数计算,要先找到小数点位置进行小数点对齐
常见大数运算方法还有分治法等,分治法把数字分成一块一块的,然后再进行整合
2.二维数组二分查找
该排序的二维数组a[m][n]特点为每行数据是有序的,每列数据是有序的
思路为:从左下角第一个数开始查找,若更大,则向上查找,若更小,则向右查找,最大时间复杂度,也只是O(m+n)
3.1TB数据如何使用32GB内存排序
采用外排序:
- 1TB分为40块,每块25GB,留一些系统空间
- 25GB读入内存,进行内部排序(如:快排)
- 把排好的数据存回磁盘
- 循环排序40块
- 从40块分别读取25GB/40入内存
- 40路合并,并将合并结合临时存储于2GB基于内存内存的输出缓冲区,写满2GB时,写入磁盘上最终文件,并清空输出缓冲区
4.找出海量数据中最大的k个数
- 小根堆
建一个大小为k的小根堆,遍历数据,前k个数先建堆,之后每当后面有数比k大,则替换根节点并调整堆 - 分治法
将数据分块,每块找到最大的k个数,再继续分块找新块的最大的k个数,重复步骤即可
5.如何让快排稳定
- 设置双标志位,不在乎空间的话,把原数组的元素包装一下,变成(元素,下标)的形式,比较时若元素相等,比较下标,排序完成后拆开就好了
- 可以用另外一个和待排序一样长度的辅助数组。对待排序数组两次扫描,第一次从下标0到len把比tmp小的依次从左到右一直放到辅助数组里。然后第二次扫描待排序数组从下标len到0,把大于等于tmp的依次从右到左放到辅助数组里。最后拷贝辅助数组到原数组,这样应该就是稳定的partition了。当然第一次扫描需要记录mid的位置,而且选择比较的tmp也要数组的第一个也就是low下标的数
6.找到有序数组中唯一相加为0的一对数
和快排的思路有些类似,快排比较的是两个数的大小,这个则是比较两个数绝对值,若绝对值大的,基准位置向左或向右移动
7.找到1-100中不存在于数组a[99]的数
给一个临时变量,依次异或1-100,再去异或数组元素,最终得到的结果即为不存在的数
8.链表相关问题
- 快慢指针法:给定一个快指针fast=fast->next->next,一个慢指针low=low->nest
解决问题:
找链表中是否有环:
如果有环,则一定会相遇
找链表中间节点:
若fast->nest为NULL,则low所在位置即中间节点
找倒数第k个节点:
设有两个指针 low,fast,fast 先走 k - 1 步,再使两个指针同时走,当 fast -> next 指向空时,返回 low即倒数第 k 个结点 - cur,prev,next指针法:也叫三指针法,cur、prev指向链表头部,next指向头部的next
解决问题:
反转链表:
给定三个指针 n1,n2,n3,n1 指向头节点,n2 指向头-> next,n3 指向头-> next -> next ,使 next 指向 prev ,即 n2 -> next = n1,n3 始终向后移动,直到 n3 指向空,即 n1 和 n2 改变指针所指方向, n3 为指针方向改变的位置
删除重复节点:
给三个指针 cur,next,prev,cur 指向第一个结点,若后移过程与 next 相等,删除 next 后 cur 再后移,直至 cur 与 next 不相等时,删除 cur ,cur 后移,prev 后移,next 后移,重新链接 prev 和新 cur,若后移过程中,cur 与 next 不相等,next、cur、prev 后移