前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >剑指 Offer 总结

剑指 Offer 总结

作者头像
离殊
发布2022-05-31 10:44:15
2060
发布2022-05-31 10:44:15
举报
文章被收录于专栏:DingLin 随笔

1: 实现 Singleton (单例) 模式

题目:设计一个类,我们只能生成该类的一个实例。

单例模式的定义是:保证一个类仅有一个实例,并提供一个访问它的全局访问点。

代码语言:javascript
复制
// Modal 类
class Modal {
  constructor(message) {
    this.message = message;
  }

  get getMessage() {
    return this.message;
  }
}

// 通过代理设计模式
// 使用闭包实现
const SingletonModal = (function () {
  let instance = null;
  return class SingletonModal {
    constructor(message) {
      if (instance === null) {
        instance = new Modal(message);
      }

      return instance;
    }
  };
})();

const Singleton1 = new SingletonModal("Singleton1");
const Singleton2 = new SingletonModal("Singleton2");

console.log(Singleton1 === Singleton2); // true
console.log(Singleton1.getMessage); // Singleton1
console.log(Singleton2.getMessage); // Singleton1

#2: 数组中重复的数字

题目一:找出数组中重复的数字

在一个长度为 n 的数组里的所有数字都在 0 ~ n - 1 的范围内。数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次。请找出数组中任意一个重复的数字。

例如,如果输入长度为 7 的数组 [2, 3, 1, 0, 2, 5, 3]

那么对应的输出是重复的数字 2 或者 3。

如不包含返回 false,如无效空指针返回 false

image
image
代码语言:javascript
复制
function duplicate(numbers) {
  if (!Array.isArray(numbers) && numbers !== null) return false;
  const length = numbers.length;

  // 如果值大于元素下标,返回 false
  for (let i = 0; i < length; ++i) {
    if (numbers[i] > length - 1) {
      return false;
    }
  }

  for (let i = 0; i < length; ++i) {
    while (i !== numbers[i]) {
      if (numbers[i] === numbers[numbers[i]]) {
        return numbers[numbers[i]];
      }
      let temp = numbers[i];
      numbers[i] = numbers[temp];
      numbers[temp] = temp;
    }
  }

  return false;
}
duplicate([2, 3, 1, 0, 2, 5, 3]); // 2
duplicate([1, 2, 3, 5]); // false
duplicate([1, 2, 3]); // false

题目二:不修改数组找出重复的数字

在一个长度为 n+1 的数组里的所有数字都在 1~n 的范围内,所以数组中至少有一个数字是重复的。请找出数组中任意一个重复的数字,但不能修改输入的数组。

例如,如果输入长度为 8 的数组 [2, 3, 5, 4, 3, 2, 6, 7]

那么对应的输出是重复的数字 2 或者 3。

代码语言:javascript
复制
// 时间 O(n) 空间 O(n)
function duplicate(numbers) {
  if (numbers.length === 0) return false;

  const arr = [];
  for (let i = 0; i < numbers.length; ++i) {
    if (arr.includes(numbers[i])) {
      return numbers[i];
    }
    arr.push(numbers[i]);
  }

  return false;
}

const arr = [2, 3, 5, 4, 3, 2, 6, 7];
console.log(duplicate(arr));
代码语言:javascript
复制
// 时间 O(nlogn) 空间 O(1)
function duplicate(numbers) {
  if (numbers.length <= 0) return -1;

  let start = 1;
  let end = numbers.length - 1;

  while (end >= start) {
    let middle = ((end - start) >> 1) + start;

    let count = countRange(numbers, start, middle);
    if (end === start) {
      if (count > 1) {
        return start;
      } else {
        break;
      }
    }

    if (count > middle - start + 1) {
      end = middle;
    } else {
      start = middle + 1;
    }
  }
  return -1;
}

function countRange(numbers, start, end) {
  if (numbers.length === 0) return 0;

  let count = 0;
  for (let i = 0; i < numbers.length; ++i) {
    if (numbers[i] >= start && numbers[i] <= end) {
      ++count;
    }
  }
  return count;
}

const arr = [2, 3, 5, 4, 3, 2, 6, 7];
console.log(duplicate(arr));

#3: 二维数组中的查找

题目描述

在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。

例如下面的二维数组就是每行、每列都递增排序。如果在这个数组中查找数字 7,则返回 true;如果查找数字 5 ,由于数组不含有该数字,则返回 false。

image
image
代码语言:javascript
复制
const arr = [
  [1, 2, 8, 9],
  [2, 4, 9, 12],
  [4, 7, 10, 13],
  [6, 8, 11, 15],
];

function find(arr, num) {
  let row = 0
  let column = arr.length - 1
  let found = false

  while(row < arr.length && row >= 0 && column >= 0) {
    const rightTop = arr[row][column]
    if (rightTop === num) {
      found = true
      break
    } else if (rightTop > num) {
      --column
    } else {
      ++row
    }
  }
  return found
}

find(arr, 7)
image
image

思考:我们也可以选取左下角的数字。但我们不能选择左上角数字或者右下角数字。以左上角数字为例,最初数字 1 位于初始数组的左上角,由于 1 小于 7,那么 7 应该位于 1 的右边或者下边。此时我们既不能从查找范围内剔除 1 所在的行,也不能剔除 1 所在的列,这样我们就无法缩小查找范围。

代码语言:javascript
复制
const arr = [
  [1, 2, 8, 9],
  [2, 4, 9, 12],
  [4, 7, 10, 13],
  [6, 8, 11, 15],
];

function find(arr, num) {
  let row = arr.length - 1
  let column = 0
  let found = false

  while(column < arr.length && row >= 0 && column >= 0) {
    if (arr[row][column] === num) {
      found = true
      break
    } else if (arr[row][column] < num) {
      ++column
    } else {
      --row
    }
  }

  return found
}

find(arr, 7)
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-04-18,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1: 实现 Singleton (单例) 模式
  • #2: 数组中重复的数字
  • #3: 二维数组中的查找
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档