前言提起数据结构与算法,大家可能第一时间想到的就是蓝桥杯这种算法竞赛,并不会太过于在意它在面试中的占比。因为在若干年前,你去面试这种互联网公司或者大的IT公司,面试官并不会过于考察你的算法能力,甚至说你会简单的写一些框架,搭一些数据库,就能找到一份不错的工作但是直至今日,大家会发现面试的门槛越来越高,甚至来说去到一些大公司去面试算法与数据结构的题目已经成为必问了,算法的在面试的占比已经越来越高,在这里我整理了一下我在近几年面试中问的比较频繁的算法题,大家感兴趣的可以看看,看自己能答出来多少。寻找数组的中心索引数组中某一个下标,左右两边的元素之后相等,该下标即为中心索引思路:先统计出整个数组的总和,然后从第一个元素开始叠加总和递减当前元素,叠加递增当前元素,直到两个值相等删除排序数组中的重复项一个有序数组 nums ,原地删除重复出现的元素,使每个元素只出现一次 ,返回删除后数组的新长度。不要使用额外的数组空间,必须在原地修改输入数组并在使用 O(1) 额外空间的条件下完成。完整的算法刷题笔记我也帮大家整理好了,需要的同学转发本文+关注+私信【0408】即可无偿获取双指针算法:数组完成排序后,我们可以放置两个指针 i 和 j,其中 i 是慢指针,而 j 是快指针。只要nums[i]=nums[j],我们就增加 j 以跳过重复项。当遇到 nums[j] != nums[i]时,跳过重复项的运行已经结束,必须把nums[j])的值复制到 nums[i +1]。然后递增 i,接着将再次重复相同的过程,直到 j 到达数组的末尾为止。x的平方根在不使用 sqrt(x) 函数的情况下,得到的 x的平方根的整数部分解法一:二分查找x的平方根肯定在0到x之间,使用二分查找定位该数字,该数字的平方一定是最接近x的,m平方值如果大于x、则往左边找,如果小于等于x则往右边找找到0和X的最中间的数m,如果m * m > x,则m取x/2到x的中间数字,直到m * m < x,m则为平方根的整数部分如果是m * m <= x,则取0到x/2的中间值,知道两边的界限重合,找到最大的整数,则为x平方根的整数部分时间复杂度:O(logN)解法二:牛顿迭代假设平方根是 i ,则 i 和 x/i 必然都是x的因子,而 x/i 必然等于 i ,推导出 i + x / i = 2 * i,得出 i = (i +x / i) / 2由此得出解法,i 可以任选一个值,只要上述公式成立,i 必然就是x的平方根,如果不成立, (i + x / i) /2得出的值进行递归,直至得出正确结论三个数的最大乘积一个整型数组 nums ,在数组中找出由三个数字组成的最大乘积,并输出这个乘积。乘积不会越界如果数组中全是非负数,则排序后最大的三个数相乘即为最大乘积;如果全是非正数,则最大的三个数相乘同样也为最大乘积。如果数组中有正数有负数,则最大乘积既可能是三个最大正数的乘积,也可能是两个最小负数(即绝对值最大)与最大正数的乘积。分别求出三个最大正数的乘积,以及两个最小负数与最大正数的乘积,二者之间的最大值即为所求答案。解法一:排序解法二:线性扫描两数之和给定一个升序排列的整数数组 numbers ,从数组中找出两个数满足相加之和等于目标数 target 。假设每个输入只对应唯一的答案,而且不可以重复使用相同的元素。返回两数组的下标值,以数组形式返回暴力解法时间复杂度:O(N的平方)空间复杂度:O(1)哈希表:将数组的值作为key存入map,target – num作为key时间复杂度:O(N)空间复杂度:O(N)解法一:二分查找先固定一个值(从下标0开始),再用二分查找另外一个值,找不到则固定值向右移动,继续二分查找时间复杂度:O(N * logN)空间复杂度:O(1)解法二:双指针左指针指向数组head,右指针指向数组tail,head+tail > target 则tail 左移,否则head右移时间复杂度:O(N)空间复杂度:O(1)斐波那契数列求取斐波那契数列第N位的值。斐波那契数列:每一位的值等于他前两位数字之和。前两位固定 0,1,1,2,3,5,8。。。。解法一:暴力递归解法二:去重递归递归得出具体数值之后、存储到一个集合(下标与数列下标一致),后面递归之前先到该集合查询一次,如果查到则无需递归、直接取值。查不到再进行递归计算解法三:双指针迭代基于去重递归优化,集合没有必要保存每一个下标值,只需保存前两位即可,向后遍历,得出N的值环形链表给定一个链表,判断链表中是否有环。如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达该节点,则链表中存在环如果链表中存在环,则返回 true 。 否则,返回 false 。解法一:哈希表解法二:双指针排列硬币总共有 n 枚硬币,将它们摆成一个阶梯形状,第 k 行就必须正好有 k 枚硬币。给定一个数字 n,找出可形成完整阶梯行的总行数。n 是一个非负整数,并且在32位有符号整型的范围内解法一:迭代从第一行开始排列,排完一列、计算剩余硬币数,排第二列,直至剩余硬币数小于或等于行数解法二:二分查找假设能排 n 行,计算 n 行需要多少硬币数,如果大于 n,则排 n/2行,再计算硬币数和 n 的大小关系解法三:牛顿迭代使用牛顿迭代求平方根,(x + n/x)/2假设能排 x 行 则 1 + 2 + 3 + …+ x = n,即 x(x+1)/2 = n 推导出 x = 2n – x合并两个有序数组两个有序整数数组 nums1 和 nums2,将 nums2 合并到 nums1 中,使 nums1 成为一个有序数组。初始化 nums1 和 nums2 的元素数量分别为 m 和 n 。假设 nums1 的空间大小等于 m + n,这样它就有足够的空间保存来自 nums2 的元素。解法一:合并后排序时间复杂度 : O((n+m)log(n+m))。空间复杂度 : O(1)。解法二:双指针 从前往后将两个数组按顺序进行比较,放入新的数组时间复杂度 : O(n + m)。空间复杂度 : O(m)。解法三:双指针优化从后往前时间复杂度 : O(n + m)。空间复杂度 : O(1)。子数组最大平均数给一个整数数组,找出平均数最大且长度为 k 的下标连续的子数组,并输出该最大平均数。滑动窗口:窗口移动时,窗口内的和等于sum加上新加进来的值,减去出去的值完整的算法刷题笔记我也帮大家整理好了,需要的同学转发本文+关注+私信【0408】即可无偿获取