推荐收藏!算法岗最常被问到的数据结构面试题总结!

节前,我们组织了一场算法岗技术&面试讨论会,邀请了一些互联网大厂朋友、参加社招和校招面试的同学,针对算法岗技术趋势、大模型落地项目经验分享、新手如何入门算法岗、该如何准备、面试常考点分享等热门话题进行了深入的讨论。

今天分享给大家算法岗最常考的数据结构的面试题,希望对后续找工作的有所帮助。喜欢记得点赞、收藏、关注。更多技术交流&面经学习,可以文末加入我们交流群。

1. 两数之和

给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出和为目标值 target 的那两个整数,并返回它们的数组下标。

你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。

你可以按任意顺序返回答案。

示例1:

输入:nums = [2,7,11,15], target = 9

输出:[0,1]

解释:因为 nums[0] + nums[1] == 9 ,返回 [0, 1]

示例 2:

输入:nums = [3,2,4], target = 6

输出:[1,2]

示例 3:

输入:nums = [3,3], target = 6

输出:[0,1]

提示:

2 <= nums.length <= 104

-109 <= nums[i] <= 109

-109 <= target <= 109

只会存在一个有效答案

代码实现:

python 复制代码
class Solution:
    def twoSum(self, nums: List[int], target: int) -> List[int]:
        for i in range(len(nums)):
            for j in range(i+1, len(nums)):
                if nums[i] + nums[j] == target:
                    return [i, j]

解题思路:嵌套遍历从数组中取出两个数相加,用嵌套的for循环,判断相加的结果是否满足要求,如果满足则用列表返回两个数据的索引。因为同一个元素不能重复出现,所以索引 j 从 i+1 开始遍历。

2. 两数相加

给你两个 非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。

请你将两个数相加,并以相同形式返回一个表示和的链表。

你可以假设除了数字 0 之外,这两个数都不会以 0 开头。

示例1:

输入:l1 = [2,4,3], l2 = [5,6,4]

输出:[7,0,8]

解释:342 + 465 = 807

示例 2:

输入:l1 = [0], l2 = [0]

输出:[0]

示例 3:

输入:l1 = [9,9,9,9,9,9,9], l2 = [9,9,9,9]

输出:[8,9,9,9,0,0,0,1]

提示:

每个链表中的节点数在范围 [1, 100] 内

0 <= Node.val <= 9

题目数据保证列表表示的数字不含前导零

代码实现:

python 复制代码
class Solution:
    def addTwoNumbers(self, l1: Optional[ListNode], l2: Optional[ListNode]) -> Optional[ListNode]:
        l1num, l2num = l1.val, l2.val
        i, j = 0, 0
        cur = l1
        while cur.next:
            cur = cur.next
            i += 1
            l1num += cur.val * 10 ** i
        cur2 = l2
        while cur2.next:
            cur2 = cur2.next
            j += 1
            l2num += cur2.val * 10 ** j
        sumnum = l1num + l2num
        result = ListNode()
        cur = result
        for s in str(sumnum)[::-1]:
            cur.next = ListNode(int(s))
            cur = cur.next
        return result.next

解题思路:先按照逆序的方式将 l1 和 l2 两个链表转化成对应的整数,转化时依次将第 i 个节点的数字乘 10 的 i 次方,并全部相加,i 从 0 开始。得到两个整数,计算两个整数之和。然后将整数之和倒序保存到链表中,每个节点一个数字。我采用的方式是将两数之和转换成字符串倒着遍历,再将每个数字转换回整数,然后创建节点添加到链表中。

3. 无重复字符的最长子串

给定一个字符串 s ,请你找出其中不含有重复字符的 最长子串 的长度。

示例1:

输入: s = "abcabcbb"

输出: 3

解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。

示例 2:

输入: s = "bbbbb"

输出: 1

解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。

示例 3:

输入: s = "pwwkew"

输出: 3

解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。

请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。

提示:

0 <= s.length <= 5 * 104

s 由英文字母、数字、符号和空格组成

代码实现:

python 复制代码
class Solution:
    def lengthOfLongestSubstring(self, s: str) -> int:
        length = 0
        for i in range(len(s)):
            slist = []
            for j in range(i, len(s)):
                if s[j] not in slist:
                    slist.append(s[j])
                else:
                    break
            length = max(length, len(slist))
        return length

解题思路:遍历字符串的索引,以每一个索引位为标志位,从标志位往后找最长的子串。最长子串的判断方式用列表实现,如果连续的字符不在列表中,则添加进列表,遇到重复的字符时跳出内循环。循环结束后计算列表的长度,并更新当前的最长长度。每次移动标志位,清空用于保存字符的列表。

4. 寻找两个正序数组的中位数

给定两个大小分别为 m 和 n 的正序(从小到大)数组 nums1 和 nums2。请你找出并返回这两个正序数组的 中位数 。

算法的时间复杂度应该为 O(log (m+n)) 。

示例1:

输入:nums1 = [1,3], nums2 = [2]

输出:2.00000

解释:合并数组 = [1,2,3] ,中位数 2

示例 2:

输入:nums1 = [1,2], nums2 = [3,4]

输出:2.50000

解释:合并数组 = [1,2,3,4] ,中位数 (2 + 3) / 2 = 2.5

提示:

nums1.length == m

nums2.length == n

0 <= m <= 1000

0 <= n <= 1000

1 <= m + n <= 2000

-106 <= nums1[i], nums2[i] <= 106

代码实现:

python 复制代码
class Solution:
    def findMedianSortedArrays(self, nums1: List[int], nums2: List[int]) -> float:
        m = len(nums1)
        n = len(nums2)
        if m > n:
            return self.findMedianSortedArrays(nums2,nums1)
        k = (m + n + 1)//2
        left = 0
        right = m
        while left < right :
            m1 = left +(right - left)//2
            m2 = k - m1
            if nums1[m1] < nums2[m2-1]:
                left = m1 + 1
            else:
                right = m1
        m1 = left
        m2 = k - m1 
        c1 = max(nums1[m1-1] if m1 > 0 else float("-inf"), nums2[m2-1] if m2 > 0 else float("-inf") )
        if (m + n) % 2 == 1:
            return c1
        c2 = min(nums1[m1] if m1 < m else float("inf"), nums2[m2] if m2 <n else float("inf"))
        return (c1 + c2) / 2

解题思路:此题在Leetcode上的难度是困难,属于等级最高的难度(简单、中等、困难),困难的原因是要求时间复杂度为O(log (m+n))。主要目的是考算法思路,并且要提交者自己实现算法。如果没有时间复杂度的要求,实现其实很简单,如下代码就可以通过力扣的用例(甚至可以更简单,导入一个求中位数的函数):

python 复制代码
class Solution:
    def findMedianSortedArrays(self, nums1: List[int], nums2: List[int]) -> float:
  nums = sorted(nums1 + nums2)
  if len(nums) % 2 == 0:
      return (nums[int(len(nums) // 2) - 1] + nums[int(len(nums) // 2)]) / 2
  else:
      return nums[len(nums) // 2]

因为要求时间复杂度为 O(log (m+n)),我一开始也没有想到好的方法,所以参考了力扣用户powcai的答案。两个数组都是正序排列的,所以找到中位数的策略是从两个数组中找出排序在前一半的数据,中间的数字就是中位数。也就是找出第 k 大的那个数字,k 是两个数组长度之和的一半,或中间的两个数(k, k+1)。

假如使用遍历,时间复杂度将会是 O(m+n),为了将时间复杂度降到题目要求的O(log (m+n)),需要使用二分法的方式查找。遍历是每次排除一个数据不是第 k 大,二分查找每次排除 k/2 个数据不是第 k 大。在这个思路的基础上,结合上面的代码就可以分析出解题办法了。如果你需要了解更详细的解题细节,可以自己再搜索更多的参考答案。

5. 最长回文子串

给你一个字符串 s,找到 s 中最长的回文子串。

如果字符串的反序与原始字符串相同,则该字符串称为回文字符串。

示例 1:

输入:s = "babad"

输出:"bab"

解释:"aba" 同样是符合题意的答案。

示例 2:

输入:s = "cbbd"

输出:"bb"

提示:

1 <= s.length <= 1000 s 仅由数字和英文字母组成

代码实现:

python 复制代码
class Solution:
    def longestPalindrome(self, s: str) -> str:
        max_length = 1
        start_index = 0
        i = 0
        while i < len(s):
            length = 1
            left = i - 1
            while left >= 0 and s[left] == s[i]:
                length += 1
                left -= 1
            right = i + 1
            while right < len(s) and s[right] == s[i]:
                length += 1
                right += 1
                i += 1
            while left >= 0 and right < len(s) and s[left] == s[right]:
                length += 2
                left -= 1
                right += 1
            if length > max_length:
                max_length = length
                start_index = left+1
            i += 1
        return s[start_index:start_index+max_length]

解题思路:要找到字符串 s 中的最长回文子串,需要找到最长回文子串的长度 max_length 和回文子串的开始索引 start_index 。因为 s 的长度最短为1,所以 max_length 最小为 1,start_index 初始为 0,以此为初始值,当找到更长的回文子串时更新两者的值。

遍历字符串的每一个字符,以每一个字符为标志位,判断标志位左侧的字符是否与标志位的字符相同,如果相同则继续向左找,每找到一个字符,回文子串的长度加1,右侧也同理。这样可以找到标志位两侧与标志位相同的所有连续字符,包含了奇数个和偶数个两种情况。

找完与标志位相同的连续字符后,再继续找左边的字符与右边的字符相同的情况,此时每找到一对相同的字符,回文子串的长度加2,直到两边的字符不同或到达字符串 s 的边界。完成后判断此次找到的最长回文长度和前面找到的长度,如果更长就更新 max_length 和 start_index 的值。

进阶:本文使用 while 循环,在向右找到与标志位相同的连续字符时,标志位的索引 i 也加1,这样可以减少 while 的遍历次数,提高程序的运行效率,跑Leetcode上提供的用例可以缩短5倍左右的时间。(同时,在这种方式的循环中,不需要向左寻找与标志位相同的连续字符,代码不会执行到。上面还保留着向左寻找的代码,是为了与解题思路保持一致,方便理解。)

技术交流

前沿技术资讯、算法交流、求职内推、算法竞赛、面试交流(校招、社招、实习)等、与 10000+来自港科大、北大、清华、中科院、CMU、腾讯、百度等名校名企开发者互动交流~

我们建了算法岗面试与技术交流群, 想要进交流群、需要源码&资料、提升技术的同学,可以直接加微信号:mlc2060。加的时候备注一下:研究方向 +学校/公司+CSDN,即可。然后就可以拉你进群了。

方式①、微信搜索公众号:机器学习社区 ,后台回复:技术交流

方式②、添加微信号:mlc2060 ,备注:技术交流+CSDN

用通俗易懂的方式讲解系列

相关推荐
风象南36 分钟前
Claude Code这个隐藏技能,让我告别PPT焦虑
人工智能·后端
Mintopia1 小时前
OpenClaw 对软件行业产生的影响
人工智能
陈广亮2 小时前
构建具有长期记忆的 AI Agent:从设计模式到生产实践
人工智能
会写代码的柯基犬2 小时前
DeepSeek vs Kimi vs Qwen —— AI 生成俄罗斯方块代码效果横评
人工智能·llm
Mintopia2 小时前
OpenClaw 是什么?为什么节后热度如此之高?
人工智能
爱可生开源社区3 小时前
DBA 的未来?八位行业先锋的年度圆桌讨论
人工智能·dba
叁两5 小时前
用opencode打造全自动公众号写作流水线,AI 代笔太香了!
前端·人工智能·agent
前端付豪6 小时前
LangChain记忆:通过Memory记住上次的对话细节
人工智能·python·langchain
strayCat232556 小时前
Clawdbot 源码解读 7: 扩展机制
人工智能·开源