经典算法面试题及解题思路

时间:2022-03-16 14:21:35

1一个数组中有若干整数,其中只有一个数只出现奇数次次,其他数都出现偶数次,找出出现奇数次的数。O(n) 

     解题思路:逐个抑或

2 统计一个字符串中出现次数最多的字符

     解题思路:count[a[i]]++;最后遍历count

3 求一个数组中的第N大的元素。O(n)

     解题思路:参考快速排序算法 每次以支点将数组分为两部分 ,递归

4 一个N个整数的无序数组,给你一个数sum,求出数组中是否存在两个数,使他们的和为sum O(nlogn)

    解题思路:先排序 在左右夹击判断

5 判断一个链表是否有环,即某个节点的next值为它前面的某个节点的地址 (Vmware )O(n)n为节点个数

    解题思路:两个指针 一个逐个前进 一个蹦着前进, 判断是否相遇

6 判断两个链表是否相交(假设无环) 如果相交,找第一个交点

    解题思路:相交的两个链表,一个尾巴,第二问 需要使用两个栈,保存指针,两个链表各自入栈,然后从尾部开始出栈

7 如何确定一个未知长度的单链表的中间点

    解题思路:两个指针,一个逐步后移,一个每次后移两个,当后者到尾时,前者位于中间,O(n) 但想法新颖

8 从一个无序数组中找出最长递减子序列,所谓子序列,其中各元素在原序列中可以不相邻 O(n^2)

    解题思路:动态规划,flag[j]代表以j为终点,且包含j在内的最长递减子序列长度 flag[j] = max(flag[i])+1 (i<j 且 a[j] < a[i]) 即在j前面的各个数字中,依次尝试将j放在其递减队列中 当满足括号内条件时,即可以放进,所有可以放进的可能中,选择使flag[j]最大的  即为flag[j]的值

9 最大子段和 O(n) 

     解题思路: 动态规划,b[j]代表以j为终点的,且包括j在内的最大连续子段和,则b[j]= max{b[j-1]+a[j], a[j]},过程中记录最大的b[j],即为所求

10 一个整数数组,要求在O(N)时间 O(1)空间内完成操作,奇数在前,偶数在后

     解题思路:数组前后两个指针,依次往中间靠拢,前指针遇到偶数,则覆盖后指针,后指针遇到奇数则覆盖前指针,需要实现保存第一个数

11 一个字符串数组,找出其中只出现了一次的字符  

     解题思路:hash  分配一个26的数组,  此题有多个衍生,如果不是字符串数组 而是其他数据,则需要分配bit数组

12 查找二叉树所有从根到叶子路径权值和为固定值的路径

    解题思路:递归,用一个栈保存路径

13 反转一个链表

     解题思路:递归

14 反转一个字符串 2 反转一个句子,但是词不能反转了

   解题思路,反转字符串可以用前后两个指针交换  然后靠近  2 反转整个句子,然后挨个反转每个词

13 复制一个复杂链表,复杂链表指的是,链表除了有一个next指针外,还有一个friend指针,指向链表中任意一个节点

  解题思路,

  思路1,先按照next指针遍历一遍,复制出一个仅包含next指针的链表,然后同时遍历新旧链表,同时各自保持两个指针,一个用来遍历节点,依次给每个节点的friend节点赋值,另一个用来定位friend节点 O(N^2)

  思路2 ,复制出来的节点先放在原节点的next,这样新节点的friend就是原节点的friend的next  O(N)

14 从一个基本有序的数组中找到最小的数,基本有序,指的是数组是由一个有序的数组截断然后拼接而成  比如345 12

     解题思路:二分查找,如果找到的数比数组最后一数大,那么在后找,如果找到的数比数组最后一数小,在前找。

15 原地归并排序

     解题思路:假设分界点为mid,两个指针分别指向两段中最小的,比如i前 j后,j=mid+1, j往后走,一直到a[j]>a[i],然后交换a[i,mid]和a[mid+1,j-1], 交换的算法,参考14题

16 求无序数组的元素间最大差值

     解题思路:最简朴的方式是二层遍历,O(n^2), 方法2是两个数组 分别记录