力扣之字串中第二大的數字

語言: CN / TW / HK

問題描述

給你一個混合字串 s ,請你返回 s第二大 的數字,如果不存在第二大的數字,請你返回 -1

混合字串由小寫英文字母和數字組成。

示例 1:

輸入:s = "dfa12321afd"
輸出:2
解釋:出現在 s 中的數字包括 [1, 2, 3] 。第二大的數字是 2 。

示例 2:

輸入:s = "abc1111"
輸出:-1
解釋:出現在 s 中的數字只包含 [1] 。沒有第二大的數字。

力扣原題目地址: https://leetcode.cn/problems/...

思路分析

方式一 先遍歷再去重再排序取最後第二大的數

  1. 首先字串中除了有數字字元,也有字母字元。所以我們在遍歷的時候,只需保留數字字元,忽略字母字元即可。這裡使用字串的 charCodeAt 方法做一個轉換判斷即可。字串0到字串9分別對應Unicode的是:

    console.log( '0'.charCodeAt() )  // 48
    console.log( '1'.charCodeAt() )  // 49
    ...... // 依次遞增
    console.log( '8'.charCodeAt() )  // 56
    console.log( '9'.charCodeAt() )  // 57
  2. 排除了字母字元以後,遍歷拿到的每一個數字字元,都可以追加到陣列中去。這樣陣列中就記錄了所有的數字字元
  3. 然後把陣列中的數字字元做一個去重,去完重以後,再做一個排序,再取第二大的數即可。程式碼如下:
var secondHighest = function (s) {
    let arr = [] // 1. 定義一個空陣列,用於儲存
    for (let i = 0; i < s.length; i++) { // 2. 遍歷,並剔除字母字元,只保留數字字元
        let item = s[i]
        if (item.charCodeAt() >= 48 & item.charCodeAt() <= 57) { // charCodeAt()方法過濾
            arr.push(item)
        }
    }
    let newArr = Array.from(new Set([...arr])) // 3. 去個重
    newArr.sort((a, b) => { // 4. 排個序
        return b - a
    })
    return newArr[1] ? newArr[1] : -1 // 5. 有第二項,就返回第二項,沒有就返回-1
};

方式二 定義倆變量表示第一大第二大的數並不斷迭代更新

  1. 定義兩個變數用來表示第一大和第二大的數
  2. 遍歷中不斷更新第一大和第二大的數字
  3. 這種定義變數通過遍歷不斷對比並比較大小的操作力扣也有類似的題目

    1. 比如:力扣之第三大的數
    2. 結合筆者之前的文章,有助於更高的理解: https://segmentfault.com/a/11...
    3. 本題程式碼如下:
var secondHighest = function (s) {
    let firstMax = -Infinity // 1. 定義一個最大的數變數(大當家)
    let secondMax = -Infinity // 2. 定義一個第二大的數變數(二當家)
    for (let i = 0; i < s.length; i++) { // 3. 遍歷操作
        let item = s[i]
        if (item.charCodeAt() >= 48 & item.charCodeAt() <= 57) { // 4. 只對數字字元做操作
            if (item > firstMax) { // 5. 若新來的這個比大當家還大
                secondMax = firstMax // 6. 那麼大當家只能屈尊成為二當家了
                firstMax = item // 7. 因為新來的成為大當家了
            } else if (item == firstMax) { // 8. 若新來的和大當家一樣,那就不變吧,忽略之
            } else if (item > secondMax) { // 9. 若新來的比二當家大(但是沒有大當家大)
                secondMax = item // 10. 那大當家就不用換,只需新來的成為二當家即可
            }
        }
    }
    // 11. 最後把 二當家返回出去(注意要做一個判斷,因為有可能secondMax還是-Infinity)
    return secondMax == -Infinity ? -1 : secondMax 
};

總結

力扣多刷幾題,就會發現,這一題好像之前做過類似的啊。

是的,所以咱們刷題的時候,注意一下,題目分類,這樣會事半功倍。

而且對於前端同學,可以優先刷 字串、陣列分類的題目(因為二叉樹、連結串列前端用的會稍微少一些)