返回

剑指 Offer JavaScript LeetCode 刷题第五天:查找算法(中等)

前端

剑指 Offer JavaScript LeetCode 刷题第五天:查找算法(中等)

导语:
欢迎来到剑指 Offer JavaScript LeetCode 刷题第五天!今天,我们将学习查找算法的中等难度题。我们将介绍几种常见的查找算法,包括暴力法、二分查找、散列表、数组和链表。我们将通过示例代码来演示这些算法的用法,并讨论它们的优缺点。最后,我们将提供一些建议,帮助您选择最合适的查找算法来解决您的问题。

暴力法:
暴力法是最简单、最直接的查找算法。它通过逐个比较目标元素与数组中的每个元素来找到目标元素。暴力法的代码很简单,但它的效率非常低,尤其是在数组很大时。

function linearSearch(array, target) {
  for (let i = 0; i < array.length; i++) {
    if (array[i] === target) {
      return i;
    }
  }
  return -1;
}

二分查找:
二分查找是一种更有效的查找算法,它利用了数组是有序的这一特性。二分查找通过不断地将数组一分为二来缩小搜索范围,从而快速找到目标元素。

function binarySearch(array, target) {
  let low = 0;
  let high = array.length - 1;

  while (low <= high) {
    let mid = Math.floor((low + high) / 2);
    if (array[mid] === target) {
      return mid;
    } else if (array[mid] < target) {
      low = mid + 1;
    } else {
      high = mid - 1;
    }
  }

  return -1;
}

散列表:
散列表是一种数据结构,它可以将键值对存储在一个数组中。散列表通过计算键的哈希值来确定键值对在数组中的位置。散列表的查找效率非常高,因为它可以直接通过键的哈希值找到键值对。

class HashTable {
  constructor(size) {
    this.table = new Array(size);
  }

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

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

  hash(key) {
    let hash = 0;
    for (let i = 0; i < key.length; i++) {
      hash += key.charCodeAt(i);
    }
    return hash % this.table.length;
  }
}

数组:
数组是一种数据结构,它可以存储一组元素。数组中的元素可以通过索引来访问。数组的查找效率非常高,因为它可以直接通过索引找到元素。

let array = [1, 2, 3, 4, 5];

console.log(array[2]); // 3

链表:
链表是一种数据结构,它由一组节点组成。每个节点包含一个值和一个指向下一个节点的指针。链表的查找效率不高,因为它需要遍历整个链表才能找到目标元素。

class Node {
  constructor(value) {
    this.value = value;
    this.next = null;
  }
}

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

  add(value) {
    let node = new Node(value);
    if (this.head === null) {
      this.head = node;
    } else {
      let current = this.head;
      while (current.next !== null) {
        current = current.next;
      }
      current.next = node;
    }
  }

  find(value) {
    let current = this.head;
    while (current !== null) {
      if (current.value === value) {
        return current;
      }
      current = current.next;
    }
    return null;
  }
}

选择合适的查找算法:
在选择合适的查找算法时,需要考虑以下因素:

  • 数组的大小
  • 数组是否有序
  • 目标元素出现的频率
  • 查找操作的频率

总结:
在本文中,我们介绍了五种常见的查找算法:暴力法、二分查找、散列表、数组和链表。我们讨论了这些算法的优缺点,并提供了一些建议,帮助您选择最合适的查找算法来解决您的问题。

练习题:

  1. 在一个无序的数组中查找一个元素。
  2. 在一个有序的数组中查找一个元素。
  3. 在一个散列表中查找一个键值对。
  4. 在一个数组中查找一个元素,并返回它的索引。
  5. 在一个链表中查找一个元素,并返回它的节点。