算法| ss 字符串数组对象

  • 13.罗马数字转整数
  • 409.最长回文串
  • 415.字符串相加
  • 594.最长和谐子序列
  • 43.字符串相乘
  • 128.最长连续序列
  • 179.最大数
  • 462.最小操作次数使数组元素相等 II
  • 692.前K个高频单词
  • 686.重复叠加字符串匹配
  • 567.字符串的排列

13. 罗马数字转整数

/**
 * @param {string} s
 * @return {number}
 */
// 构建map匹配值,增加带IV这种的
// for遍历循环,
// 1.先看匹配是否满足2个字符的 i+2
// 2. 单个字符匹配
var romanToInt = function (s) {
  const map = {
    I: 1,
    IV: 4,
    V: 5,
    IX: 9,
    X: 10,
    XL: 40,
    L: 50,
    XC: 90,
    C: 100,
    CD: 400,
    D: 500,
    CM: 900,
    M: 1000,
  };
  let ans = 0;
  for (let i = 0; i < s.length; i++) {
    const substr = s.substring(i, i + 2);
    if (i + 1 < s.length && map[substr]) {
      ans += map[substr];
      i += 1;
    } else {
      ans += map[s[i]];
    }
  }
  //   console.log(ans);
  return ans;
};
// romanToInt("III");
// romanToInt("IV");
romanToInt("MCMXCIV");
// 示例 1:
// 输入: s = "III"
// 输出: 3
// 示例 2:
// 输入: s = "IV"
// 输出: 4

409.最长回文串

/**
 * @param {string} s
 * @return {number}
 */
// 思路
// 统计各个字符出现的次数
// 统计奇数个数, 只留一个奇数个数,其他个数删除1
// 如果奇数个数大于1
// 总长度= 字符串长度- (奇数个数-1)
//
var longestPalindrome = function (s) {
  const map = {};
  for (let ch of s) {
    map[ch] = (map[ch] ?? 0) + 1;
  }
  let deleteCount = 0;
  for (let key in map) {
    if (map[key] % 2 !== 0) {
      deleteCount += 1;
    }
  }
  const ans = deleteCount > 1 ? s.length - (deleteCount - 1) : s.length;
  //   console.log(ans);
  return ans;
};
longestPalindrome("abccccdd");

// 输入:s = "abccccdd"
// 输出:7

415. 字符串相加

/**
 * @param {string} num1
 * @param {string} num2
 * @return {string}
 */
// 思路
// 从两个数的末尾进行取值 相加
// while循环很重要, i>=0 j>=0  carry>=0
// 往数组里添加 求余值放入数组  进位值进入下一轮计算
var addStrings = function (num1, num2) {
  let i = num1.length - 1;
  let j = num2.length - 1;
  let carry = 0;
  const res = [];
  while (i >= 0 || j >= 0 || carry !== 0) {
    let c1 = i >= 0 ? num1.charAt(i) - "0" : 0;
    let c2 = j >= 0 ? num2.charAt(j) - "0" : 0;
    // console.log("c1", c1);
    // console.log("c2", c2);
    const sum = c1 + c2 + carry;
    res.push(sum % 10);
    carry = Math.floor(sum / 10);
    i--;
    j--;
  }
  //   console.log(res);
  return res.reverse().join("");
};
addStrings("11", "123");
// 输入:num1 = "11", num2 = "123"
// 输出:"134"

594.最长和谐子序列

/**
 * @param {number[]} nums
 * @return {number}
 */
// 思路
// 统计各个数出现的次数
// 利用map 来获取最大值
// map是有序的, 不想对象是无序的
var findLHS = function (nums) {
  const map = new Map();
  for (let ch of nums) {
    map.set(ch, (map.get(ch) ?? 0) + 1);
  }
  console.log(map);
  let max = 0;
  for (let key of map.keys()) {
    if (map.get(key + 1)) {
      max = Math.max(max, map.get(key) + map.get(key + 1));
    }
  }
  console.log(max);
  return max;
};
findLHS([1, 3, 2, 2, 5, 2, 3, 7]);
// 输入:nums = [1,3,2,2,5,2,3,7]
// 输出:5

43. 字符串相乘

/**
 * @param {string} num1
 * @param {string} num2
 * @return {string}
 */
// 思路
// 两个数相乘 结果的长度不会超过两个数长度的和 9*9 = 81
// 从结尾开始相乘 res[i + j + 1] 为 i j的位置
// res[i + j + 1] 求余
// res[i + j] 存进位
var multiply = function (num1, num2) {
  const len1 = num1.length;
  const len2 = num2.length;
  const res = Array(len1 + len2).fill(0);
  for (let i = len1 - 1; i >= 0; i--) {
    const n1 = +num1[i];
    for (let j = len2 - 1; j >= 0; j--) {
      const n2 = +num2[j];
      const multi = n1 * n2;
      const sum = res[i + j + 1] + multi;
      res[i + j + 1] = sum % 10;
      res[i + j] += (sum / 10) | 0;
    }
  }
  while (res[0] === 0) {
    res.shift();
  }
  let ans = res.length ? res.join("") : "0";
  console.log(ans);
  return ans;
};
multiply("2", "3");
multiply("123", "456");

128. 最长连续序列

/**
 * @param {number[]} nums
 * @return {number}
 */
// 思路
// 数组排序
// 边界数组1个的情况
// for循环遍历 初始为1
// 如果当前和前一个数相等 则continue
// 如果当前比前一个数大1,temp++
// 否则 temp置为初始1
// Math.max更新结果
var longestConsecutive = function (nums) {
  if (nums.length === 0) return 0;
  nums.sort((a, b) => a - b);
  let ans = 1;
  let temp = 1;
  for (let i = 1; i < nums.length; i++) {
    if (nums[i] === nums[i - 1]) continue;
    if (nums[i] - nums[i - 1] === 1) {
      temp += 1;
    } else {
      temp = 1;
    }
    ans = Math.max(ans, temp);
  }
  console.log(ans);
  return ans;
};
longestConsecutive([100, 4, 200, 1, 3, 2, 2]);
longestConsecutive([0, 3, 7, 2, 5, 8, 4, 6, 0, 1]);
// 输入:nums = [100,4,200,1,3,2]
// 输出:4

179. 最大数

/**
 * @param {number[]} nums
 * @return {string}
 */
// 思路
// 字符串排序 两个数转string进行拼接比较
var largestNumber = function (nums) {
  nums.sort((a, b) => {
    let stra = b.toString() + a.toString();
    let strb = a.toString() + b.toString();
    console.log(stra, strb);
    return stra > strb ? 1 : -1;
  });
  if (nums[0] === 0) return "0";
  console.log(nums.join(""));
  return nums.join("");
};
largestNumber([3, 30, 34, 5, 9]);
// 输入:nums = [3,30,34,5,9]
// 输出:"9534330"

462. 最小操作次数使数组元素相等 II

/**
 * @param {number[]} nums
 * @return {number}
 */
// 思路
// 数组排序 找到中间值val
// for遍历数组, 取各个数和中间值的绝对值差之和
var minMoves2 = function (nums) {
  nums.sort((a, b) => a - b);
  const mid = Math.floor(nums.length / 2);
  const midValue = nums[mid];
  let result = 0;
  for (let ch of nums) {
    result += Math.abs(ch - midValue);
  }
  console.log(result);
  return result;
};
minMoves2([1, 2, 3]);

// 输入:nums = [1,2,3]
// 输出:2
// 解释:
// 只需要两次操作(每次操作指南使一个元素加 1 或减 1):
// [1,2,3]  =>  [2,2,3]  =>  [2,2,2]

692.前K个高频单词

/**
 * @param {string[]} words
 * @param {number} k
 * @return {string[]}
 */
// 思路
// 哈希统计+ sort排序
var topKFrequent = function (words, k) {
  const map = {};
  for (let ch of words) {
    map[ch] = (map[ch] ?? 0) + 1;
  }
  let ans = Object.keys(map).sort((a, b) =>
    map[a] === map[b] ? (a > b ? 1 : -1) : map[b] - map[a]
  );
  //   console.log(ans.slice(0, k));
  return ans.slice(0, k);
};
topKFrequent(["i", "love", "leetcode", "i", "love", "coding"], 2);

// 输入: words = ["i", "love", "leetcode", "i", "love", "coding"], k = 2
// 输出: ["i", "love"]
// 解析: "i" 和 "love" 为出现次数最多的两个单词,均为2次。
//     注意,按字母顺序 "i" 在 "love" 之前。

686.重复叠加字符串匹配

/**
 * @param {string} a
 * @param {string} b
 * @return {number}
 */
// 思路
// 把a至少拼接成b的长度 判断有没有包含b
// 如果不包含再拼接一次(可能是头尾的关系),判断是否包含, 包含更新结果,不包含返回-1
var repeatedStringMatch = function (a, b) {
  if (!b.length) return 0;
  let targetStr = a;
  let len = b.length;
  let result = 1;
  while (targetStr.length < len) {
    targetStr += a;
    result += 1;
  }
  if (targetStr.includes(b)) {
    return result;
  }

  targetStr += a;
  result += 1;
  if (targetStr.includes(b)) {
    return result;
  } else {
    return -1;
  }
};
console.log(repeatedStringMatch("abcd", "cdabcdab"));

567.字符串的排列

/**
 * @param {string} s1
 * @param {string} s2
 * @return {boolean}
 */
// 思路 固定滑窗 + 哈希统计
// 这里也只有2个元素好解决, 两个指针一一对应, 如果s1 数量比2大 ,就不好搞了
//   left 和right 相隔2个元素
//   right的作用是消掉 left的作用是补上
var checkInclusion = function (s1, s2) {
  const map = {};
  for (let ch of s1) {
    map[ch] = (map[ch] ?? 0) + 1;
  }
  let k = s1.length;
  let right = 0;
  let left = 0;
  while (right < k) {
    let ch = s2[right];
    if (map[ch]) map[ch]--;
    right++;
  }
  if (Object.values(map).every((item) => item <= 0)) return true;
  //   left 和right 相隔2个元素
  //   right的作用是消掉 left的作用是补上
  for (let right = k; right < s2.length; right++) {
    let leftCh = s2[left];
    let rightCh = s2[right];
    if (map[leftCh] != undefined) map[leftCh] += 1;
    if (map[rightCh] != undefined) map[rightCh] -= 1;
    // console.log("left-right", left, right);
    left += 1;
    if (Object.values(map).every((item) => item <= 0)) return true;
  }
  return false;
};
console.log(checkInclusion("ab", "eidbaooo"));
console.log(checkInclusion("ab", "aidboaoo"));
// 输入:s1 = "ab" s2 = "eidbaooo"
// 输出:true
// 解释:s2 包含 s1 的排列之一 ("ba").
// 示例 2:

// 输入:s1= "ab" s2 = "eidboaoo"
// 输出:false

// left-right 0 2
// left-right 1 3
// left-right 2 4
// true
// left-right 0 2
// left-right 1 3
// left-right 2 4
// left-right 3 5
// left-right 4 6
// left-right 5 7
// false
  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值