数据结构常用技巧

数组

1、如何寻找数组中最大最小值

  • 分别找出最大值和最小值
  • 维持2个变量min和max,每次取一个元素先与已找到的最小值比较,再与已找到的最大值比较
  • 维持2个变量min和max,每次比较相邻两个数,较大者与max比较,较小者与min比较,通过比较找出最大值和最小值
  • 将数组中相邻的两个数分在一组,每次比较相邻的数,将较大值变换至这两个数左边,较小值放于右边,对大者组扫描一次找到最大值,对小者组扫描一次找到最小值
  • 将数组划分为两半,分别找出两边的最大值和最小值,则最终的最大值是两边最大中的较大者,最小值是两边最小中的较小者

2、如何找出数组中第二大的数

  • 将数组排序,然后根据数组下标访问数组中第二大的数
  • 设置2个变量,一个用于存储最大值,另一个用于存储第二大的值,然后遍历数组元素,如果数组元素比最大值大,则将第二大的值变量更新为原来的最大值,将最大值变量更新为该元素,如果数组元素的值比最大值小,那么比较该元素和第二大的值,如果比第二大的值大,那么更新第二大的值的变量为该元素

3、如何求最大子数组之和

  • 找出所有子数组,然后求出子数组的和,在所有子数组的和中取最大值
  • 在上一个方法的基础上,重复利用已经计算的子数组的和
  • 动态规划
  • 优化的动态规划

4、如何找出数组中重复元素最多的数

  • (空间换时间)定义一个数组int count[MAX],并将其数组元素都初始化为0,然后执行for(int i=0;i<100;I++) count[A[i]]++;并在count数组中找出最大的数,即重复次数最多的数
  • 使用Map映射表来记录每一个元素的次数,然后判断次数大小,进而找出重复次数最多的元素

5、如何求数组中两两相加等于20的组合种数

  • 采用双重循环遍历数组来判断两个数的和是否为20
  • 先对数组进行排序,然后对排序后的数组分别从前到后和从后到前遍历

6、如何把一个数组循环右移K位

  • 在数组中有2段序列的顺序不变,分别逆序这2段子数组,然后全部逆序整个数组

7、如何找出数组中第k个最小的数

  • 对数组进行排序,排序后的数组中第k-1个位置上的数字即为数组的第k个最小的数
  • 选取一个数作为枢纽,把比它小的数都放在它的左边,比它大的数都放在它的右边,然后判断枢纽的位置,如果为k-1那么就是它,如果小于k-1那么第k个最小的数在右半部分,采用递归的方式查找右半部分,否则在左半部分

8、如何找出数组中只出现一次的数

  • 对数组排序,然后遍历数组,比较相邻的两个数,从而找出只出现1次的数
  • 根据异或运算的定义,任何一个数字异或它自己都等于0;从头到尾一次异或数组中的每一个数字,那些出现2次的数全部在异或中被抵消,最终的结果刚好是只出现一次的数字
  • 如果数字重复出现N次,那么对数组中所有数字对应的二进制数中个位置上1的个数对n取余数,可以得到出现1次的这个数对应的二进制表示,从而得到这个数

9、如何找出数组中唯一的重复元素

  • 使用大小为n的位图,记录每个元素是否已经出现过,一旦遇到一个已经出现过的元素,则直接输出
  • 先对数字排序,然后遍历整个数组,一旦遇到一个已经出现的元素就输出
  • 把遍历到的元素取反,只出现一次的元素都是小于0的,出现一个大于0的数,则输出

10、递归方法求一个整数数组的最大元素

  • 数组的第一个元素与数组中其他元素组成的子数组的最大值的最大值

11、如何求数对之差的最大值

  • 遍历数组找到所有可能的差值,从所有差值中找出最大值
  • 把数组分为2个子数组,那么最大的差值只能有3种情况:最大差值对应的被减数和减数都在左边;最大差值对应的被减数和减数都在右边;被减数是做子数组的最大值,减数是右子数组的最小值,找到这三者中最大的就是最大差值
  • 动态规划

12、如何求绝对值最小的数

  • 求绝对值最小的数可以分为三种情况:如果数组第一个元素为非负数,那么绝对值最小的数就是数组的第一个元素;如果数组最后一个元素为负数,那么绝对值最小的数肯定是数组的最后一个数;数组中既有正数又有负数时,找到正数与负数的分界点,如果分界点为0,就是它,否则通过比较分界点左右的正数和负数的绝对值来确定最小的数

13、如何求数组中2个元素的最小距离

  • 遍历数组当遇到n1时,记录下数组的下标,并计算此下标与上次一道n2的下标的差;当遇到n2时,记录下数组的下标,并计算此下标与上次一道n1的下标的差,定义一个变量记录最小距离,将这2个差与它比较

14、如何求指定数字在数组中第一次出现的位置

  • 假设指定数字为t顺序遍历数值中的每一个元素,并且将数组中的元素与t进行比较,如果相等,返回下标

15、如何对数组的2个子有序段进行合并

  • 遍历前一个有序段,将遍历到的元素和后一个有序段的头元素比较,当前者大于后者, 交换他们的值,然后找到后者交换后的位置,继续遍历,直到遍历结束

16、如何计算2个有序整型数组的交集

  • 当2个数组长度相当,分别从头开始遍历2个数组,遇到相等的元素,则为交集,然后继续遍历,如果前一个大于后一个,那么继续遍历后一个,如果前一个小于后一个,那么继续遍历前一个,直到有一个结束则结束
  • 同时遍历2个数组,并将数组元素存在哈希表中,同时对统计的数组元素进行计数,计数为2的就是交集
  • 将其中一个数组遍历并存储在散列表中,然后遍历另一个并在散列表中查询,存在则为交集
  • 如果2个数组长度相差很大,依次遍历长度短的数组,将遍历得到的元素在长数组中进行二分查找

17、如何判断一个数组中的数是否连续相邻

  • 假设判断5个数是否连续相邻,那么最大值和最小值的差距必然是4

18、如何求解数组中反序对的个数

  • 对数组中的每一个数字,遍历它后面的所有数字,如果后面的数字比它小,那么就找到一个逆序对

19、如何求解最小三元组距离

  • 遍历3个数组中的元素,分别求出它们的距离,然后从这些值里面查找最小的值
  • 假设当前遍历到3个数组中的元素分别是Ai,Bi,Ci,且,Ai<=Bi<=Ci,那么距离为Ci-Ai;如果接下来求Ai,Bi,Ci+1,因为Ci+1>Ci,所以距离不满足最小;Ai,Bi+1,Ci,Bi+1>Bi,如果Bi+1

链表

1、如何从链表中删除重复数据

  • (空间换时间)遍历链表,把遍历到的值存储到一个Map中,在遍历过程中,若当前访问的值在Map中已经存在,则说明这个数据是重复的,可以删除
  • 对链表进行双重循环遍历,外循环正常遍历链表,假设外循环当前遍历的结点是current,内循环从current开始遍历,若碰到与current指向结点值相同,则删除这个重复结点

2、如何找出单链表中的倒数第K个元素

  • 首先遍历一遍单链表,求出整个单链表的长度n,然后将倒数第K个转换为正数第n-K个,然后再次遍历链表就能得到结果
  • 在查找的过程中,设置两个指针,让其中一个指针比另一个指针先移动K-1步,然后两个指针同时往前移动,循环直到先行的指针值为NULL时,另一个指针所指的位置就是索要找的位置

3、如何实现链表的反转

  • 定义3个相邻的指针(i,m,n),反转指针的指向,需要注意的是一旦调整了指针的指向,链表就断开了,没有指针指向结点你,没办法再遍历到结点n,所以为了避免链表断开,需要在调整m的next之前把n保存下来

4、如何从尾到头输出单链表

  • 改变链表的方向,然后重新遍历并输出单链表
  • (空间换时间)从头到尾遍历单链表,每经过一个结点,就把结点放到一个栈中,遍历完整个链表之后,就从栈顶开始输出结点的值
  • 递归本质就是一个栈结构,要实现反过来输出一个链表,每访问到一个结点,先递归输出它后面的结点,再输出该结点自身,这样链表输出的结果就是反过来的
public void printListReversely( Node pListHead){
    if(pListHead != null){
        printListReversely(pListHead.next);
        System.out.println(pListHead.data);
    }
}

5、如何寻找单链表的中间结点

  • 先遍历求得单链表的长度length,然后遍历length/2的激距离,就可以找到单链表的中间结点
  • 两个指针同时从头开始遍历,一个指针一次走2步,一个指针一次走1步,快指针先到链表尾部,而慢指针则恰好到达链表中部(当链表长度为奇数时,慢指针指向的是链表中间指针,当链表长度为偶数时,慢指针指向的结点和下一个结点都是链表的中间结点)

6、如何检测一个链表是否有环

  • 两个指针同时从头开始遍历,一个指针一次走2步,一个指针一次走1步,快指针每移动一次都要和慢指针比较,直到当快指针等于慢指针为止,证明这个链表是带环的单向链表(快指针先到链表尾部,说明是无环的)

7、如何找到单链表中环的入口

  • 在链表头和相遇点分别设置一个指针,每次各走一步,两个指针必定相遇,且相遇第一点为环入口点

8、如何在不知道头指针的情况下删除指定结点

  1. 若待删除的结点为链表的尾结点,则无法删除,因为删除后无法使其前驱节点的next指针置为空
  2. 若待删除的结点不是尾结点,则可以通过交换这个结点与其后继结点的值,然后删除后继结点

9、如何判断2个链表是否相交

  • 如果2个链表相交,那么它们必定有相同的尾结点,分别遍历2个链表,记录它们的尾结点,如果他们的尾结点相同,那么这2个链表相交,否则不相交

10、如果2个链表相交,如何找到他们相交的第一个结点

  • 分别计算2个链表的长度len1,len2(假设len1 > len2);然后对链表1遍历len1-len2个结点到达结点p,此时p与另一个链表的头结点到他们相交点的距离相同,同时遍历链表,直到遇到相同的结点为止,这个结点就是相交的结点
  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值