返回

字节跳动算法面试题精解:JavaScript篇

前端

字节跳动作为国内互联网巨头,其算法面试题一直备受关注。本文将对字节跳动算法面试题进行精解,帮助您在面试中脱颖而出。

1. 数据结构

数据结构是算法的基础,也是字节跳动算法面试题的重中之重。常见的数据结构包括数组、链表、栈、队列、哈希表和树。您需要掌握这些数据结构的基本概念、操作方法和应用场景。

// 数组
const arr = [1, 2, 3];
arr.push(4); // 向数组末尾添加元素
arr.pop(); // 删除数组末尾的元素
arr.unshift(0); // 向数组开头添加元素
arr.shift(); // 删除数组开头的元素

// 链表
class Node {
  constructor(data) {
    this.data = data;
    this.next = null;
  }
}

class LinkedList {
  constructor() {
    this.head = null;
    this.tail = null;
  }

  add(data) {
    const node = new Node(data);
    if (!this.head) {
      this.head = node;
      this.tail = node;
    } else {
      this.tail.next = node;
      this.tail = node;
    }
  }

  remove(data) {
    let current = this.head;
    let previous = null;
    while (current) {
      if (current.data === data) {
        if (!previous) {
          this.head = current.next;
        } else {
          previous.next = current.next;
        }
        if (current === this.tail) {
          this.tail = previous;
        }
        break;
      }
      previous = current;
      current = current.next;
    }
  }
}

// 栈
class Stack {
  constructor() {
    this.items = [];
  }

  push(item) {
    this.items.push(item);
  }

  pop() {
    return this.items.pop();
  }

  peek() {
    return this.items[this.items.length - 1];
  }

  isEmpty() {
    return this.items.length === 0;
  }
}

// 队列
class Queue {
  constructor() {
    this.items = [];
  }

  enqueue(item) {
    this.items.push(item);
  }

  dequeue() {
    return this.items.shift();
  }

  peek() {
    return this.items[0];
  }

  isEmpty() {
    return this.items.length === 0;
  }
}

// 哈希表
class HashMap {
  constructor() {
    this.table = {};
  }

  put(key, value) {
    this.table[key] = value;
  }

  get(key) {
    return this.table[key];
  }

  remove(key) {
    delete this.table[key];
  }

  isEmpty() {
    return Object.keys(this.table).length === 0;
  }
}

// 树
class Tree {
  constructor() {
    this.root = null;
  }

  add(data) {
    const node = new Node(data);
    if (!this.root) {
      this.root = node;
    } else {
      this.insertNode(node, this.root);
    }
  }

  insertNode(node, parent) {
    if (node.data < parent.data) {
      if (!parent.left) {
        parent.left = node;
      } else {
        this.insertNode(node, parent.left);
      }
    } else {
      if (!parent.right) {
        parent.right = node;
      } else {
        this.insertNode(node, parent.right);
      }
    }
  }

  find(data) {
    let current = this.root;
    while (current) {
      if (current.data === data) {
        return current;
      } else if (data < current.data) {
        current = current.left;
      } else {
        current = current.right;
      }
    }
    return null;
  }

  remove(data) {
    this.root = this.removeNode(data, this.root);
  }

  removeNode(data, node) {
    if (!node) {
      return null;
    }
    if (data === node.data) {
      // 没有子节点的情况
      if (!node.left && !node.right) {
        return null;
      }
      // 只有一个子节点的情况
      if (!node.left) {
        return node.right;
      } else if (!node.right) {
        return node.left;
      }
      // 有两个子节点的情况
      let successor = node.right;
      while (successor.left) {
        successor = successor.left;
      }
      node.data = successor.data;
      node.right = this.removeNode(successor.data, node.right);
      return node;
    } else if (data < node.data) {
      node.left = this.removeNode(data, node.left);
      return node;
    } else {
      node.right = this.removeNode(data, node.right);
      return node;
    }
  }
}

2. 动态规划

动态规划是一种常用的算法范式,用于解决具有重叠子问题的