LeetCode每周五题_2024/01/08~01/12

本文档提供了四个编程题目及其解法,涉及计算回旋镖数量、在字符串中删除子串后的最小长度、构造有效字符串所需的最少插入数以及统计出现一次的公共字符串。这些题目主要与IT技术中的数据结构、字符串处理和算法设计相关。
摘要由CSDN通过智能技术生成

447. 回旋镖的数量 [01/08]

题目

给定平面上 n 对 互不相同 的点 points ,其中 points[i] = [xi, yi] 。回旋镖 是由点 (i, j, k) 表示的元组 ,其中 i 和 j 之间的距离和 i 和 k 之间的欧式距离相等(需要考虑元组的顺序)。
返回平面上所有回旋镖的数量。

题解

/**
 * @param {number[][]} points
 * @return {number}
 */
var numberOfBoomerangs = function (points) {
    let ans = 0; // 回旋镖数量
    const distanceCounts = new Map(); // 固定点到其他点的距离
    for (let [x1, y1] of points) {
        distanceCounts.clear(); //端点变化,重新记忆
        // 固定点坐标
        for (let [x2, y2] of points) {
            // 端点到固定点距离
            const dis = (x1 - x2) ** 2 + (y1 - y2) ** 2;
            // 端点到固定点距离相同 点数量
            const c = distanceCounts.get(dis) ?? 0;
            // [i, x , y] [i, y, x] 顺序算两个
            ans += c * 2;
            // 距离相同点数+1
            distanceCounts.set(dis, c + 1);
        }
    }
    return ans;
};

2707. 字符串中的额外字符 [01/09]

题目

给你一个下标从 0 开始的字符串 s 和一个单词字典 dictionary 。你需要将 s 分割成若干个 互不重叠 的子字符串,每个子字符串都在 dictionary 中出现过。s 中可能会有一些 额外的字符 不在任何子字符串中。
请你采取最优策略分割 s ,使剩下的字符 最少 。

题解

/**
 * @param {string} s
 * @param {string[]} dictionary
 * @return {number}
 */
var minExtraChar = function (s, dictionary) {
  // dp表 每个字符对应剩余字符的最优解
  const dpMap = new Array(s.length + 1).fill(0);
  //循环字符串找到每一个字符串的最优解
  for (let i = 0; i < s.length; i++) {
    // 当前字符串
    const cur = s.slice(0, i + 1);
    // 剩余字符串默认+1
    dpMap[i + 1] = dpMap[i] + 1;
    for (let item of dictionary) {
      // 循环单词字典找到包含在cur字符串的
      if (cur.endsWith(item)) {
        // 此时最优剩余字符 就是当前的剩余 和 当前匹配字符初始前字符剩余长度 对比
        dpMap[i + 1] = Math.min(dpMap[i + 1], dpMap[i - item.length + 1]);
      }
    }
  }
  return dpMap[dpMap.length - 1];
};

2696. 删除子串后的字符串最小长度 [01/10]

题目

给你一个仅由 大写 英文字符组成的字符串 s 。

你可以对此字符串执行一些操作,在每一步操作中,你可以从 s 中删除 任一个 “AB” 或 “CD” 子字符串。

通过执行操作,删除所有 “AB” 和 “CD” 子串,返回可获得的最终字符串的 最小 可能长度。

注意,删除子串后,重新连接出的字符串可能会产生新的 “AB” 或 “CD” 子串。

题解

/**
 * @param {string} s
 * @return {number}
 */
var minLength = function (s) {
  let stack = []; //栈
  for (let key of s) {
    stack.push(key);
    if (stack.length >= 2) {
      const newStr = stack[stack.length - 2] + stack[stack.length - 1];
      if (newStr === "AB" || newStr === "CD") {
        stack.pop();
        stack.pop();
      }
    }
  }
  return stack.length;
};

2645. 构造有效字符串的最少插入数

题目

给你一个字符串 word ,你可以向其中任何位置插入 “a”、“b” 或 “c” 任意次,返回使 word 有效 需要插入的最少字母数。

如果字符串可以由 “abc” 串联多次得到,则认为该字符串 有效 。

题解

/**
 * @dec 动态规划 DP
 * @param {string} word
 * @returns {number}
 */
var addMinimum = function (word) {
  const n = word.length;
  const d = new Array(n + 1).fill(0);
  for (let i = 1; i <= n; i++) {
    // 默认插入两个字母组成符合的字符串
    d[i] = d[i - 1] + 2;
    // charCodeAt c > b 98 > a 97
    if (i > 1 && word[i - 1] > word[i - 2]) {
      d[i] = d[i - 1] - 1;
    }
  }
  return d[n];
};

/**
 * @dec 栈
 * @param {string} word
 * @return {number}
 */
var addMinimum = function (word) {
  let stack = []; //  栈
  let sum = 0;

  for (let i = 0; i < word.length + 2; i++) {
    if (i < word.length) {
      stack.push(word[i]);
    }
    // 循环结束前,栈里字母长度3 或者 单词循环结束,栈里还有值
    if (stack.length === 3 || (i >= word.length && stack.length)) {
      // 3个字母直接有效
      if (stack[0] + stack[1] + stack[2] === "abc") {
        stack.length = 0;
      } else if (["ab", "ac", "bc"].includes(stack[0] + stack[1])) {
        // 是否只缺一个字母就组成有效字符串
        sum += 1;
        stack.shift();
        stack.shift();
      } else {
        sum += 2;
        stack.shift();
      }
    }
  }
  return sum;
};

2085. 统计出现过一次的公共字符串

题目

给你两个字符串数组 words1 和 words2 ,请你返回在两个字符串数组中 都恰好出现一次 的字符串的数目。

题解

/**
 * @param {string[]} words1
 * @param {string[]} words2
 * @return {number}
 */
var countWords = function (words1, words2) {
  // hash表
  let hashMap = new Map();
  let sum = 0;
  for (let i = 0; i < words1.length; i++) {
    const key = words1[i];
    if (hashMap.get(key)) {
      hashMap.set(key, hashMap.get(key) + 2);
    } else {
      hashMap.set(key, 1);
    }
  }
  for (let i = 0; i < words2.length; i++) {
    const key = words2[i];
    if (hashMap.get(key)) {
      hashMap.set(key, hashMap.get(key) + 1);
    }
  }
  hashMap.forEach((value, key) => {
    if (value === 2) {
      sum++;
    }
  });
  return sum;
};
  • 8
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值