leetCode之数组操作

首页目录 点击查看

第一题

  • 难度:中等
  • 题目:54. 螺旋矩阵
    给定一个包含 m x n 个元素的矩阵(m 行, n 列),请按照顺时针螺旋顺序,返回矩阵中的所有元素。

示例

输入:
[
 [ 1, 2, 3 ],
 [ 4, 5, 6 ],
 [ 7, 8, 9 ]
]
输出: [1,2,3,6,9,8,7,4,5]

输入:
[
  [1, 2, 3, 4],
  [5, 6, 7, 8],
  [9,10,11,12]
]
输出: [1,2,3,4,8,12,11,10,9,5,6,7]

解题思路

  • 这道题我得想法是,通过方向判断,在边界内找到,下一个数排入数组的数是什么,用turn分别表示上下左右四个放下,每改变一次方向,代表着它刚所处的行或者列不可再被选中,就要缩小边界。

我的答案

var spiralOrder = function (matrix) {
    let array = []
    if (!matrix.length) return array
    let row = 0;
    let len = matrix.length;
    let rowLen = matrix[0].length
    let col = 0;
    let turn = rowLen - 1 === 0 ? "b" : "r"
    let boxL = 0;
    let boxR = rowLen - 1;
    let boxU = 0;
    let boxD = len - 1;

    while (array.length < (len * rowLen)) {
        !array.includes(matrix[row][col]) && array.push(matrix[row][col])
        if (turn === 'b') {
            row++
            if (row == boxD) {
                boxR--
                turn = 'l'
            }
        } else if (turn === 'l') {
            col--
            if (col == boxL) {
                boxD--
                turn = 't'
            }
        } else if (turn === 't') {
            row--
            if (row == boxU) {
                boxL++
                turn = 'r'
            }
        } else if (turn === 'r') {
            col++
            if (col == boxR) {
                boxU++
                turn = 'b'
            }
        }
    }
    return array
};
image.png

第二题

  • 难度:简单
  • 题目: 59. 螺旋矩阵 II
    给定一个正整数 n,生成一个包含 1 到 n2 所有元素,且元素按顺时针顺序螺旋排列的正方形矩阵。
示例
输入: 3
输出:
[
 [ 1, 2, 3 ],
 [ 8, 9, 4 ],
 [ 7, 6, 5 ]
]

解题思路

  • 这道题和第一题基本思路是一样的,只是说根据,顺序填入数字就可以了,所以这里只需要创建一个变量num用于保存递增的数字。

我的答案

var generateMatrix = function (n) {
    let array = [];
    let row = 0;
    let col = 0;
    let num = 0;
    let turn = "r"
    let boxL = 0;
    let boxR = n - 1;
    let boxU = 0;
    let boxD = n - 1;
    if (n === 0) return array;
    while (num < (n * n)) {
        num += 1;
        if (!array[row]) {
            array[row] = []
        };
        array[row][col] = num;
        if (turn === 'b') {
            row++

            if (row == boxD) {
                boxR--
                turn = 'l'
            }
        } else if (turn === 'l') {
            col--
            if (col == boxL) {
                boxD--
                turn = 't'
            }
        } else if (turn === 't') {
            row--
            if (row == boxU) {
                boxL++
                turn = 'r'
            }
        } else if (turn === 'r') {
            col++
            if (col == boxR) {
                boxU++
                turn = 'b'
            }
        }
    }
    return array
};
image.png

第三题

  • 难度:中等
  • 题目:73. 一维数组的动态和
    给定一个 m x n 的矩阵,如果一个元素为 0,则将其所在行和列的所有元素都设为 0。请使用原地算法

示例

输入: 
[
  [1,1,1],
  [1,0,1],
  [1,1,1]
]
输出: 
[
  [1,0,1],
  [0,0,0],
  [1,0,1]
]

解题思路

  • 这道题首先遍历一次,取出需要清空的行和列角标,然后分别取出角标清空原有数据

我的答案

var setZeroes = function (matrix) {
    let len = matrix.length
    let rowLen = matrix[0].length
    let row = 0;
    let col = 0
    let num = 0;
    let changeRow = []
    let changeCol = []
    while (num < (len * rowLen)) {
        num++;
        if (matrix[row][col] === 0) {
            !changeRow.includes(row) && changeRow.push(row);
            !changeCol.includes(col) && changeCol.push(col)
        }
        if (col < rowLen - 1) {
            col++
        } else {
            col = 0
            row++
        }
    }
    while (changeRow.length || changeCol.length) {
        while (changeCol.length) {
            let sRow = 0;
            let tcol = changeCol.pop()
            while (sRow <= len - 1) {
                matrix[sRow][tcol] = 0
                sRow++
            }
        }
        while (changeRow.length) {
            let sCol = 0;
            let trow = changeRow.pop()
            while (sCol <= rowLen - 1) {
                matrix[trow][sCol] = 0
                sCol++
            }
        }
    }
    return matrix
};
image.png

第四题

  • 难度:中等
  • 题目:1395. 统计作战单位数
    n 名士兵站成一排。每个士兵都有一个 独一无二 的评分 rating 。
    每 3 个士兵可以组成一个作战单位,分组规则如下:
    从队伍中选出下标分别为 i、j、k 的 3 名士兵,他们的评分分别为 rating[i]、rating[j]、rating[k]
    作战单位需满足: rating[i] < rating[j] < rating[k] 或者 rating[i] > rating[j] > rating[k] ,其中 0 <= i < j < k < n
    请你返回按上述条件可以组建的作战单位数量。每个士兵都可以是多个作战单位的一部分。

示例

输入:rating = [2,5,3,4,1]
输出:3
解释:我们可以组建三个作战单位 (2,3,4)、(5,4,1)、(5,3,1) 。

输入:rating = [2,1,3]
输出:0
解释:根据题目条件,我们无法组建作战单位。

解题思路

  • 这道题首先想到的是非常暴力的三循环遍历,然后看了题解的答案发现了枚举中间点的方法处理,性能更佳。我们也可以枚举三元组 (i, j, k)(i,j,k) 中的 j,它是三元组的中间点。在这之后,我们统计:
    出现在位置 j 左侧且比 j 评分低的士兵数量 leftLess;
    出现在位置 j 左侧且比 j 评分高的士兵数量 leftMore;
    出现在位置 j 右侧且比 j 评分低的士兵数量 rightless;
    出现在位置 j 右侧且比 j 评分高的士兵数量 rightMore。
    这样以来,任何一个出现在 leftLess中的士兵 j,以及出现在rightMore中的士兵 z,都可以和 i组成一个严格单调递增的三元组;同理,任何一个出现在 leftMore中的士兵 j,以及出现在rightless中的士兵 k,都可以和 i 组成一个严格单调递减的三元组。因此,以 jj 为中间点的三元组的数量为:
    num += leftLess * rightMore + leftMore * rightLess
    我们将所有的值进行累加即可得到答案。

我的答案

  • 暴力三循环
        var numTeams = function (rating) {
            let num = 0;
            for (let i = 0; i <= rating.length - 1; i++) {
                for (let j = i + 1; j <= rating.length - 1; j++) {
                    for (let z = j + 1; z <= rating.length - 1; z++) {
                        if (rating[i] < rating[j] && rating[j] < rating[z]) {
                            num += 1
                        } else if (rating[i] > rating[j] && rating[j] > rating[z]) {
                            num += 1
                        }
                    }
                }
            }
            return num
        };
  • 时间复杂度:O(N3)

  • 空间复杂度: O(1)


    image.png
  • 枚举中间点

        var numTeams = function (rating) {
            let num = 0;
            for (let i = 0; i <= rating.length - 1; i++) {
                let leftLess = 0,
                    leftMore = 0;
                let rightLess = 0,
                    rightMore = 0;
                for (let j = 0; j <= i; j++) {
                    if (rating[j] > rating[i]) {
                        leftMore += 1
                    }
                    if (rating[j] < rating[i]) {
                        leftLess += 1
                    }
                }
                for (let z = i + 1; z <= rating.length - 1; z++) {
                    if (rating[z] > rating[i]) {
                        rightMore += 1
                    }
                    if (rating[z] < rating[i]) {
                        rightLess += 1
                    }
                }
                num += leftLess * rightMore + leftMore * rightLess
            }
            return num
        };
  • 时间复杂度:O(N2)
  • 空间复杂度: O(1)


    image.png

第五题

  • 难度:困难
  • 题目:#### 57. 插入区间
    给出一个无重叠的 ,按照区间起始端点排序的区间列表。
    在列表中插入一个新的区间,你需要确保列表中的区间仍然有序且不重叠(如果有必要的话,可以合并区间)。

示例

输入:intervals = [[1,3],[6,9]], newInterval = [2,5]
输出:[[1,5],[6,9]]

输入:intervals = [[1,2],[3,5],[6,7],[8,10],[12,16]], newInterval = [4,8]
输出:[[1,2],[3,10],[12,16]]
解释:这是因为新的区间 [4,8] 与 [3,5],[6,7],[8,10] 重叠。

解题思路

  • 其实这道题很简单的,一来不要被困难给吓住了,先把两个数组合并,并且根据第一个数字排序。
    创建一个数组arr,放入合并后数组的第一个元素,然后让后面的的数组的第二个数字和arr数组的最后的元素第二个数字做比较,相交就取大的值,不相交则直接添加到arr中。

我的答案

var insert = function (intervals, newInterval) {
    intervals.push(newInterval);
    intervals.sort((a, b) => a[0] - b[0]);
    if (intervals.length <= 1) return intervals
    let arr = [ intervals[0]];
    for (let i = 1; i <= intervals.length - 1; i++) {
        if (arr[arr.length - 1][1] >= intervals[i][0]) {
            arr[arr.length - 1][1] = Math.max(arr[arr.length - 1][1], intervals[i][1])
        } else {
            arr.push(intervals[i])
        }
    }
    return arr
};
image.png
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 221,635评论 6 515
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 94,543评论 3 399
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 168,083评论 0 360
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,640评论 1 296
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,640评论 6 397
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 52,262评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,833评论 3 421
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,736评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 46,280评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,369评论 3 340
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,503评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 36,185评论 5 350
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,870评论 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,340评论 0 24
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,460评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,909评论 3 376
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,512评论 2 359