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内存排序

采用外排序:

  1. 1TB分为40块,每块25GB,留一些系统空间
  2. 25GB读入内存,进行内部排序(如:快排)
  3. 把排好的数据存回磁盘
  4. 循环排序40块
  5. 从40块分别读取25GB/40入内存
  6. 40路合并,并将合并结合临时存储于2GB基于内存内存的输出缓冲区,写满2GB时,写入磁盘上最终文件,并清空输出缓冲区

4.找出海量数据中最大的k个数

  1. 小根堆
    建一个大小为k的小根堆,遍历数据,前k个数先建堆,之后每当后面有数比k大,则替换根节点并调整堆
  2. 分治法
    将数据分块,每块找到最大的k个数,再继续分块找新块的最大的k个数,重复步骤即可

5.如何让快排稳定

  1. 设置双标志位,不在乎空间的话,把原数组的元素包装一下,变成(元素,下标)的形式,比较时若元素相等,比较下标,排序完成后拆开就好了
  2. 可以用另外一个和待排序一样长度的辅助数组。对待排序数组两次扫描,第一次从下标0到len把比tmp小的依次从左到右一直放到辅助数组里。然后第二次扫描待排序数组从下标len到0,把大于等于tmp的依次从右到左放到辅助数组里。最后拷贝辅助数组到原数组,这样应该就是稳定的partition了。当然第一次扫描需要记录mid的位置,而且选择比较的tmp也要数组的第一个也就是low下标的数

6.找到有序数组中唯一相加为0的一对数

和快排的思路有些类似,快排比较的是两个数的大小,这个则是比较两个数绝对值,若绝对值大的,基准位置向左或向右移动

7.找到1-100中不存在于数组a[99]的数

给一个临时变量,依次异或1-100,再去异或数组元素,最终得到的结果即为不存在的数

8.链表相关问题

  1. 快慢指针法:给定一个快指针fast=fast->next->next,一个慢指针low=low->nest
    解决问题:
    找链表中是否有环:
    如果有环,则一定会相遇
    找链表中间节点:
    若fast->nest为NULL,则low所在位置即中间节点
    找倒数第k个节点:
    设有两个指针 low,fast,fast 先走 k - 1 步,再使两个指针同时走,当 fast -> next 指向空时,返回 low即倒数第 k 个结点
  2. 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 后移