找出指定元素出现的所有位置

  1. // 使用indexOf,从前往后查
  2. const findAllIndex = (arr, ele) => {
  3. let index = arr.indexOf(ele)
  4. const result = []
  5. while (index !== -1) {
  6. result.push(index)
  7. index = arr.indexOf(ele, index + 1)
  8. }
  9. return result
  10. }
  11. console.log(findAllIndex(['a', 'b', 'c', 'b'], 'b')); // [1,3]
  12. // 使用lastIndexOf,从后往前查
  13. const findAllIndex = (arr, ele) => {
  14. let index = arr.lastIndexOf(ele)
  15. const result = []
  16. while (index !== -1) {
  17. result.push(index)
  18. index = index > 0 ? arr.lastIndexOf(ele, index - 1) : -1
  19. }
  20. return result
  21. }
  22. console.log(findAllIndex(['a', 'b', 'c', 'a'], 'a')); // [3,1]

计算数组中每个元素出现的次数

  • 方法一:使用reduce

    1. const arr = ["b", "c", "b", "c", "a", "b", "c"]
    2. const newObj = (arr) => {
    3. return arr.reduce((obj, key) => {
    4. obj[key] ? obj[key]++ : obj[key] = 1
    5. return obj
    6. }, {})
    7. }
    8. console.log(newObj(arr)); // { b: 3, c: 3, a: 1 }
  • 方法二:使用普通遍历

    1. const arr = ["b", "c", "b", "c", "a", "b", "c"]
    2. const newObj = (arr) => {
    3. let result = {}
    4. arr.forEach(item => {
    5. result[item] ? result[item]++ : result[item] = 1
    6. })
    7. return result
    8. }
    9. console.log(newObj(arr)); // { b: 3, c: 3, a: 1 }

    反转字符串

    题目描述:编写一个函数,其作用是将输入的字符串反转过来。输入字符串以字符数组 s 的形式给出。

    链接:https://leetcode-cn.com/problems/reverse-string/

    1. 输入:s = ["h","e","l","l","o"]
    2. 输出:["o","l","l","e","h"]

    解法:

  • 方法一:双指针

    • 思路:定义两个指针,一个指向开始,一个指向结束,中间不断交换,左指针不断右移,右指针不断左移,直到左指针大于右指针为止
    • 复杂度分析

时间复杂度:O(N),其中 N 为字符数组的长度。一共执行了 N/2次的交换。
空间复杂度:O(1)。只使用了常数空间来存放若干变量。

  • 代码 ```javascript var reverseString = function(s) { for(let left=0,right=s.length-1;left<right;left++,right—){ [s[left],s[right]]= [s[right],s[left]] } return s };

// 或者 var reverseString = function(s) { let left=0; let right=s.length-1; while(left<right){ const temp=s[left] s[left++]=s[right] s[right—]=temp } return s };

  1. - **方法二:备份数组,更改原数组**
  2. ```javascript
  3. var reverseString = function(s) {
  4. const copy=[...s].reverse()
  5. for(let i=0,len=s.length;i<len;i++){
  6. s[i]=copy[i]
  7. }
  8. return copy
  9. };

反转字符串中的单词

给定一个字符串 s ,你需要反转字符串中每个单词的字符顺序,同时仍保留空格和单词的初始顺序。

链接:https://leetcode-cn.com/problems/reverse-words-in-a-string-iii/

  • 方法一:二分法
    • 思路:可以当成一个个单词的处理,对于每个单词,都可以采用双指针的思路来交换得到新的单词,再把处理的单词拼接起来,得到结果。
    • 复杂度分析

时间复杂度:O(N),其中 N 为字符数组的长度。一共执行了 N/2次的交换。
空间复杂度:O(1)。只使用了常数空间来存放若干变量。

var reverseWords = function(s) {
    const result=s.split(' ')
    for(let i=0;i<result.length;i++){
        const array=result[i].split('')
        let left=0,right=array.length-1
        while(left<=right){
            [array[left],array[right]]=[array[right],array[left]]
            left++;
            right--;
            // const temp=array[left]
            // array[left++]=array[right]
            // array[right--]=temp
        }
        result[i]=array.join('')
    }
    return result.join(' ')
};

千位分割数

题目描述:给你一个整数 n,请你每隔三位添加点(即 “.” 符号)作为千位分隔符,并将结果以字符串格式返回。

链接:https://leetcode-cn.com/problems/thousand-separator/

  • 方法一:暴力法

    var thousandSeparator = function(n) {
      n=n.toString().split('')
      for(let i=n.length-3;i>0;i-=3){
          n.splice(i,0,'.')
      }
      return n.join('')
    };
    
  • 方法二:toLocaleString+正则大法

    var thousandSeparator = function(n) {
      return (n).toLocaleString().replace(/\,/g, '.')
    };
    
  • 方法三:正则断言法

    var thousandSeparator = function(n) {
      // 正向零宽断言: (?=p)
      // 反向零宽断言: (?!p)
      // 可同时支持多个断言,"且" 关系
      // 如: (?=p1)(?!p2) 是既满足 p1 模式,也要不满足 p2 模式
      return String(n).replace(/(?!^)(?=(\d{3})+$)/g,'.')
    };
    

    验证回文串

    给定一个字符串,验证它是否是回文串,只考虑字母和数字字符,可以忽略字母的大小写。本题中,我们将空字符串定义为有效的回文串。

    链接:https:/https://leetcode-cn.com/problems/valid-palindrome/

  • 方法一:正则法+reverse()

    var isPalindrome = function(s) {
      if(!s && s.length<1) return false
      const valid=s.match(/[a-zA-Z0-9]+/g)
      if(!valid) return true // 处理空字符串
      let handleStr=valid.join("").toLowerCase()
      let reverseStr=handleStr.split('').reverse().join('')
      return handleStr===reverseStr
    };
    
  • 方法二:双指针

    var isPalindrome = function(s) {
      if(!s || s.length<1) return false
      const valid=s.toLowerCase().match(/[a-zA-Z0-9]+/g)
      if(!valid) return true
      const result=valid.join("")
      let left=0,right=result.length-1
      while(left<right){
          if(result[left]===result[right]){
              left++;
              right--
          }else{
              return false
          }
      }
      return true
    };
    

    罗马数字转整数

    罗马数字包含以下七种字符: I, V, X, L,C,D 和 M。

    例如, 罗马数字 2 写做 II ,即为两个并列的 1 。12 写做 XII ,即为 X + II 。 27 写做 XXVII, 即为 XX + V + II 。
    通常情况下,罗马数字中小的数字在大的数字的右边。但也存在特例,例如 4 不写做 IIII,而是 IV。数字 1 在数字 5 的左边,所表示的数等于大数 5 减小数 1 得到的数值 4 。同样地,数字 9 表示为 IX。这个特殊的规则只适用于以下六种情况:
    I 可以放在 V (5) 和 X (10) 的左边,来表示 4 和 9。
    X 可以放在 L (50) 和 C (100) 的左边,来表示 40 和 90。
    C 可以放在 D (500) 和 M (1000) 的左边,来表示 400 和 900。
    给定一个罗马数字,将其转换成整数。

    字符          数值
    I             1
    V             5
    X             10
    L             50
    C             100
    D             500
    M             1000
    

    链接:https:/https://leetcode-cn.com/problems/valid-palindrome/

  • 解法:

罗马数字转换规则:判断每个字符对应的十进制数字,核心在于比较当前字符和下一个罗马字符的关系,当下一个罗马字符所对应的数字比当前罗马字符对应的数字大的时候,当前数字对应的数值应该取负值。
时间:O(n),空间O(1)

var romanToInt = function(s) {
    const hashMap = { 'I': 1, 'V': 5, 'X': 10, 'L': 50, 'C': 100, 'D': 500, 'M': 1000};
    return s.split('').reduce((prev,curr,index,array)=>hashMap[curr<hashMap[array[index+1]]?prev-hashMap[curr]:prev+hashMap[curr],0)
}