面试官问出这几道算法题,你能扛住么?

简介: 现在的大厂越来越注重算法题,往往会被用来衡量你的代码能力,作为想要顺利拿到大厂offer的你,算法是必不可缺的一项技能,通过我的文章,带你刷爆剑指offer,吊打面试官,斩获大厂offer,以下的题目很多都是在字节跳动等大厂出现过的题目,大家可以学习一下!

前言


现在的大厂越来越注重算法题,往往会被用来衡量你的代码能力,作为想要顺利拿到大厂offer的你,算法是必不可缺的一项技能,通过我的文章,带你刷爆剑指offer,吊打面试官,斩获大厂offer,以下的题目很多都是在字节跳动等大厂出现过的题目,大家可以学习一下!


剑指offer十题


题目一


考点


答案


题目二


考点


答案


题目三


考点


答案


题目四


考点


答案


题目五


考点


答案


题目六


考点


答案


题目七


考点


答案


题目八


考点


答案


题目九


考点


答案


题目十


考点


答案


题目一


剑指 Offer 03. 数组中重复的数字


题目链接:剑指offer03 力扣


考点


哈希表,排序


答案


哈希表是一种数据结构,也是散列表的一种,通过关键码值进行直接访问的数据结构,通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度。


这道题用到的就是哈希表,哈希表的结构是:number-boolean,number 就是数组中的数字,boolean 代表数字是否出现过,我们可以通过遍历数组中的数字,检查是否出现过,如果出现过,那么返回此数字。


代码如下:


/**
 * @param {number[]} nums
 * @return {number}
 */
var findRepeatNumber = function(nums)
{
    const map = {};
    for (const num of nums)
    {
        if (!map[num])
        {
            map[num] = true;
        }
        else
        {
            return num;
        }
    }
};


题目二


剑指 Offer 05. 替换空格


题目链接:剑指offer05 力扣


考点


双指针,字符串


答案


双指针算法 所谓双指针,指的是在遍历对象的过程中,不是普通的使用单个指针进行访问,而是使用两个相同方向或者相反方向的指针进行扫描,从而达到相应目的,没学过的同学可以去学习一下。


先遍历一次字符串,统计出字符串中空格的总数,可以计算出替换之后的字符串的总长度,每替换一个空格,长度加2,替换以后字符串的长度等于原来的长度加上2*空格数

从后向前把字符串中的空格替换成%20。


/**
 * @param {string} s
 * @return {string}
 */
var replaceSpace = function(s) {
  if (s == null || !s.length)
  {
    return "";
  }
  s = s.split("");
  let kongge = 0;
  let i = 0;
  while (i < s.length)
  {
    if (s[i] == " ")
    {
      kongge++;
    }
    i++;
  }
  let newLength = s.length - 1 + kongge * 2;
  let indexOfOrigin = s.length - 1;
  let indexOfNew = newLength;
  while (indexOfOrigin >= 0 && indexOfNew > indexOfOrigin)
  {
    if (s[indexOfOrigin] == " ")
    {
      s[indexOfNew--] = "0";
      s[indexOfNew--] = "2";
      s[indexOfNew--] = "%";
    }
    else
    {
      s[indexOfNew--] = s[indexOfOrigin];
    }
    indexOfOrigin--;
  }
  return s.join("");
};


题目三


剑指 Offer 10- I. 斐波那契数列


题目链接:斐波那契数列 力扣


考点


动态规划,递推


答案


这道题是很经典的动态规划问题,是用动态规划来解决,不懂的小伙伴呢可以去学习一下这种解题思路。


我们通过计算可以推出状态转移方程dp[i] = dp[i - 1] + dp[i - 2]


dp[i]含义:斐波那契数列的第i个数为dp[i]


dp数组初始化:题目已经给出:分别是0和1


记得每次取模哦


const fib = n =>
{
    const dp = [0, 1];
    for (let i = 2; i <= n; i++)
    {
        dp[i] = (dp[i - 1] + dp[i - 2]) % 1000000007;
    }
    return dp[n];
};


题目四


剑指 Offer 10- II. 青蛙跳台阶问题


题目链接:力扣 跳台阶


考点


动态规划


答案


也是一道非常经典的动态规划问题,和斐波那契那题差不多,推一下状态转移方程

dp[i] = dp[i - 1] + dp[i - 2]


dp[i]含义:dp[i]是到第i层楼梯有多少跳法


dp数组初始化:两个1


在第 n - 2 层时,一次性跨两层(只有这一种爬法)


在第 n - 1 层时,一次性跨一层(只有这一种爬法)


/**
 * @param {number} n
 * @return {number}
 */
var numWays = function(n) {
    if(!n || n === 1)
    {
      return 1;
    }
    let dp = [1, 1];
    for(let i = 2; i <= n; i++)
    {
        dp[i] = (dp[i - 1] + dp[i - 2]) % 1000000007;
    }
    return dp[n];
};


题目五


剑指 Offer 22. 链表中倒数第k个节点


题目链接:力扣力扣


考点


链表,双指针


答案


链表是一种链式存储的数据结构,链表的特性,使其在某些操作上很高效。例如当进行插入和删除操作时,链表操作的时间复杂度仅为O(1)。另外,因为链表在内存中不是连续存储的,所以可以充分利用内存中的碎片空间。


这道题目依旧还是使用双指针,让快指针先走k步,然后快慢指针开始前进,当快指针走到链表末尾时,慢指针所在的位置就是倒数第k个链表节点


/**
 * @param {ListNode} head
 * @param {number} k
 * @return {ListNode}
 */
var getKthFromEnd = function (head, k)
{
  let dummyNode = new ListNode(-1);
  dummyNode.next = head;
  let fast = dummyNode,
    slow = dummyNode;
  while (fast && k)
  {
    fast = fast.next;
    k--;
  }
  while (fast)
  {
    fast = fast.next;
    slow = slow.next;
  }
  return slow;
};


题目六


剑指 Offer 24. 反转链表


题目链接:力扣力扣


考点


链表,递归


答案


首先遍历所有的节点,然后存储下一个节点nextNode,把当前节点赋值为上一个节点,最后一个nextNode为null,就结束了。


/**
 * Definition for singly-linked list.
 * function ListNode(val) {
 *     this.val = val;
 *     this.next = null;
 * }
 */
/**
 * @param {ListNode} head
 * @return {ListNode}
 */
var reverseList = function(head)
{
  let preNode = null
  let curNode = head
  while (curNode)
  {
    const nextNode = curNode.next
    curNode.next = preNode
    preNode = curNode
    curNode = nextNode
  }
  return preNode
};


题目七


剑指 Offer 27. 二叉树的镜像


题目链接:二叉树


考点


搜索,二叉树


答案


二叉树:树是一种重要的非线性数据结构,直观地看,它是数据元素(在树中称为节点)按分支关系组织起来的结构。二叉树(Binary Tree)是每个节点最多有两个子树的有序树。通常子树被称作"左子树"(left subtree)和"右子树"(rightsubtree)。二叉树常被用于实现二叉查找树和二叉堆。二叉树不是树的特殊情形。在图论中,二叉树是一个连通的无环图,并且每一个顶点的度不大于3。有根二叉树还要满足根节点的度不大于2。有了根节点后,每个顶点定义了唯一的根节点,和最多2个子节点。然而,没有足够的信息来区分左节点和右节点,二叉树通过链式存储来保存值,遍历方法有前序遍历,中序遍历,后序遍历,深度优先搜索,广度优先搜索。


首先我们需要递归遍历原来这棵树的左子树和右子树。然后把这棵树的左节点赋给原来的右节点(对调换),直到节点为null为止。


/**
 * Definition for a binary tree node.
 * function TreeNode(val) {
 *     this.val = val;
 *     this.left = this.right = null;
 * }
 */
/**
 * @param {TreeNode} root
 * @return {TreeNode}
 */
var mirrorTree = function(root)
{
    if (root==null)
    {
        return null;
    }
    const l = mirrorTree(root.left);
    const r = mirrorTree(root.right);
    root.left = r;
    root.right = l;
    return root;
};


题目八


剑指 Offer 31. 栈的压入、弹出序列


题目链接:力扣力扣


考点


栈,数组,模拟


答案


栈:栈是一种操作受限的线性表只允许从一端插入和删除数据。栈有两种存储方式,即线性存储和链接存储(链表)。栈的一个最重要的特征就是栈的插入和删除只能在栈顶进行,所以每次删除的元素都是最后进栈的元素,故栈也被称为后进先出表。每个栈都有一个栈顶指针,它初始值为-1,且总是指向最后一个入栈的元素,栈有两种处理方式,即进栈(push)和出栈(pop),因为在进栈只需要移动一个变量存储空间。


这题我们用辅助栈stack模拟入栈的过程,每入一个就判断一次,入栈一次判断这个栈的栈顶是否和出栈的一致,一样的话这个数据就出栈,然后指针移到下一位比较


/**
 * @param {number[]} pushed
 * @param {number[]} popped
 * @return {boolean}
 */
var validateStackSequences = function(pushed, popped)
{
  let stack=[],i=0;
  for(let n of pushed)
  {
      stack.push(n);
      while(stack.length&&stack[stack.length-1]===popped[i])
      {
          stack.pop();
          ++i;
      }
  }
  return stack.length===0;
};


题目九


剑指 Offer 53 - I. 在排序数组中查找数字 I


题目链接:力扣力扣


考点


数组,map,二分


答案


这道题可以用map,也可以用二分,看个人的理解~


我们这里使用对象存储,遍历一遍数组,当查找key有对应的value时,value+,否则就表明该数字第一次出现,将value设置为1,最终输出的结果要考虑结果是否在数组。


/**
 * @param {number[]} nums
 * @param {number} target
 * @return {number}
 */
var search = function(nums, target)
{
    let map = {}
    for(let item of nums)
    {
        if(map[item])
        {
            map[item]++
        }
        else
        {
            map[item] = 1
        }
    }
    let res = map[target] ? map[target] : 0
    return res
};


题目十


剑指 Offer 64. 求1+2+…+n


题目链接:力扣!


考点


位运算。


答案


求 1+2+…+n ,要求不能使用乘除法、for、while、if、else、switch、case等关键字及条件判断语句(A?B:C)。


我们这里使用递归解决,&& 特性:如果左边为 false,不执行右边; 左边为true继续执行右边。


/**
 * @param {number} n
 * @return {number}
 */
var sumNums = function(n)
{
  return n&&sumNums(n-1)+n;
};


目录
相关文章
|
6天前
|
负载均衡 NoSQL 算法
一天五道Java面试题----第十天(简述Redis事务实现--------->负载均衡算法、类型)
这篇文章是关于Java面试中Redis相关问题的笔记,包括Redis事务实现、集群方案、主从复制原理、CAP和BASE理论以及负载均衡算法和类型。
一天五道Java面试题----第十天(简述Redis事务实现--------->负载均衡算法、类型)
|
3月前
|
负载均衡 算法 应用服务中间件
面试题:Nginx有哪些负载均衡算法?Nginx位于七层网络结构中的哪一层?
字节跳动面试题:Nginx有哪些负载均衡算法?Nginx位于七层网络结构中的哪一层?
94 0
|
12天前
|
算法 Go
[go 面试] 雪花算法与分布式ID生成
[go 面试] 雪花算法与分布式ID生成
|
4天前
|
算法
聊聊一个面试中经常出现的算法题:组合运算及其实际应用例子
聊聊一个面试中经常出现的算法题:组合运算及其实际应用例子
|
13天前
|
机器学习/深度学习 算法 数据中心
【机器学习】面试问答:PCA算法介绍?PCA算法过程?PCA为什么要中心化处理?PCA为什么要做正交变化?PCA与线性判别分析LDA降维的区别?
本文介绍了主成分分析(PCA)算法,包括PCA的基本概念、算法过程、中心化处理的必要性、正交变换的目的,以及PCA与线性判别分析(LDA)在降维上的区别。
29 4
|
12天前
|
算法
突击面试:解密面试官的算法题集合
突击面试:解密面试官的算法题集合
|
16天前
|
算法
分享几道大厂面试算法题
分享几道大厂面试算法题
|
1月前
|
算法 Java
Java面试题:解释垃圾回收中的标记-清除、复制、标记-压缩算法的工作原理
Java面试题:解释垃圾回收中的标记-清除、复制、标记-压缩算法的工作原理
33 1
|
2月前
|
消息中间件 算法 Java
抖音面试:说说延迟任务的调度算法?
Netty 框架是以性能著称的框架,因此在它的框架中使用了大量提升性能的机制,例如 Netty 用于实现延迟队列的时间轮调度算法就是一个典型的例子。使用时间轮调度算法可以实现海量任务新增和取消任务的时间度为 O(1),那么什么是时间轮调度算法呢?接下来我们一起来看。 ## 1.延迟任务实现 在 Netty 中,我们需要使用 HashedWheelTimer 类来实现延迟任务,例如以下代码: ```java public class DelayTaskExample { public static void main(String[] args) { System.ou
36 5
抖音面试:说说延迟任务的调度算法?
|
1月前
|
算法 Java 程序员
Java面试题:解释Java的垃圾回收机制,包括常见的垃圾回收算法。介绍一下Java的垃圾回收算法中的标记-压缩算法。
Java面试题:解释Java的垃圾回收机制,包括常见的垃圾回收算法。介绍一下Java的垃圾回收算法中的标记-压缩算法。
26 0

热门文章

最新文章