这道题我一开始想复杂了,我想的是用分治的思想去解决这个问题。

  • 对于每一列的字符进行分组,建立递推关系。
  • 难点是前一组如果删除了某一列,那么之后的组应该跳过那一列的检查。
  • 当前列开始往后的子串中,删除的列数等于每一组删除的列数之和。
var minDeletionSize = function(A) {
    const len = A.length;
    if (len <= 1) {
        return 0;
    }
    const deletedLevels = new Set();
    return helper(A, 0, len-1, 0, deletedLevels);
};

function helper(A, start, end, level, deletedLevels) {
    if (level >= A[0].length) {
        return 0;
    }
    if (deletedLevels.has(level)) {
        return helper(A, start, end, level+1, deletedLevels);
    }
    if (start >= end) {
        return 0;
    }
    const blocks = [];
    let i = start;
    while (i <= end) {
        let j = i;
        while (i <= end-1) {
            if (A[i][level] === A[i+1][level]) {
                i++;
            } else if (A[i][level].charCodeAt(0) > A[i+1][level].charCodeAt(0)) {
                deletedLevels.add(level);
                const sum = helper(A, start, end, level, deletedLevels) + 1;
                return sum;
            } else {
                break;
            }
        }
        blocks.push([j, i]);
        i++;
    }
    let sum = 0;
    for (let i = 0; i < blocks.length; i++) {
        sum += helper(A, blocks[i][0], blocks[i][1], level+1, deletedLevels);
    }
    return sum;
}

另一种非常精妙的解法是建立boolean数组存储当前字符串是否已经是排序状态。

  • 首先扫描一列,如果存在逆序,则删除这一列
  • 如果没有逆序,则再扫描一遍,看看哪些字符串的顺序已经确定(除了字符相同的顺序不定)
var minDeletionSize = function(A) {
    const len = A.length;
    if (len <= 1) {
        return 0;
    }
    const sorted = new Array(len);
    for (let i = 0; i< len; i++) {
        sorted[i] = false;
    }
    const levels = A[0].length;
    let res = 0;
    for (let l = 0; l < levels; l++) {
        let shouldDelete = false;
        for (let i = 0; i < len-1; i++) {
            if (!sorted[i] && A[i][l].charCodeAt(0) > A[i+1][l].charCodeAt(0)) {
                shouldDelete = true;
                res++;
                break;
            }
        }
        if (!shouldDelete) {
            for (let i = 0; i < len-1; i++) {
                if (A[i][l].charCodeAt(0) < A[i+1][l].charCodeAt(0)) {
                    sorted[i] = true;
                }
            }
        }
    }
    return res;
};

results matching ""

    No results matching ""