数组题目:485. 最大连续1的个数 、 495. 提莫攻击 、414. 第三大的数 、628. 三个数的最大乘积、54. 螺旋矩阵 、 59. 螺旋矩阵 II 、498. 对角线遍历

485. 最大连续1的个数 

思路:

设置两个参数,count统计当前连续1的个数,maxcount统计连续最长的个数。如果遍历nums遇到了0,就maxcount = max(count,maxcount)。

代码:

class Solution {
    public int findMaxConsecutiveOnes(int[] nums) {
        int count = 0;
        int maxcount = 0;
        for(int i = 0;i < nums.length; i++){
            if(nums[i] == 1){
                count ++;
            }else{
                maxcount = Math.max(count, maxcount);
                count = 0;
            }
        }
        maxcount = Math.max(count, maxcount);
        return maxcount;
    }
}

495. 提莫攻击

思路:

这个题目要考虑两个情况

如果前一段的中毒时间结束了,再次中毒的情况,比如[1, 2] duration = 2,第一段的中毒时间为[1, 2],第三秒是第二段中毒时间的起始时间,但是timeSeries[1]=2,所以第一段还没有结束,第二段就开始了

如果前一段的中毒时间还没有结束,又开始第二次中毒的情况。比如[1, 4] ,duration= 2,第一段结束时间是2,timeSeries[1]=4,所以第一段结束了,第二段才开始。

代码:

class Solution {
    public int findPoisonedDuration(int[] timeSeries, int duration) {
        // 这个题要考虑两个情况
        // 1、当前一段的中毒时间结束之后,再中毒 比如[1, 4] duration=2,
        // 第一组的中毒时间范围是[1, 2] 第二段开始的时间是4,此时第一组的已经结束了
        // 2、当前一段的中毒时间还没有结束,但是已经开始第二段中毒了, 
        //比如[1, 2] 第一组的中毒时间在[1, 2] ,第二段按照第一个情况,中毒的起始时间是3,但是他是2,属于再前一个中毒时间内,再次中毒
        // ans 是中毒的时间累计, expire 表示每次中毒的最后时间
        int ans = 0, expire = 0;
        for(int i = 0; i < timeSeries.length; i++){
            if(timeSeries[i] >= expire){
                ans += duration;
            }else{
                ans += timeSeries[i] + duration - expire;
            }
            //更新一下中毒结束的时间
            expire = timeSeries[i] + duration;
        }
        return ans;
    }
}

414. 第三大的数 

思路:

这个题要考虑两个情况:

  • 非空数组的大小小于3或者第三大的数不存在

如果是这个情况,就返回最大的数

  • 非空数组存在第三大的数

返回第三个最大的数

代码:

class Solution {
    public int thirdMax(int[] nums) {
        TreeSet<Integer> set = new TreeSet<>();
        Arrays.sort(nums);
        for(int i = nums.length - 1; i >= 0; i--){
            set.add(nums[i]);
            if(set.size() >= 3){
                return nums[i];
            }
        }
        return nums[nums.length - 1];
    }
}

628. 三个数的最大乘积

思路:

我们先把数组排序,从小到大。

两个情况:

全都为正数,答案就是nums[nums.length - 1] * nums[nums.length - 2] * nums[nums.length - 3],全都为负数,答案就是nums[nums.length - 1] * nums[0] * nums[1]

如果数组中有正数有负数,则最大乘积既可能是三个最大正数的乘积,也可能是两个最小负数(即绝对值最大)与最大正数的乘积。

代码:

class Solution {
    public int maximumProduct(int[] nums) {
        Arrays.sort(nums);
        int n = nums.length;
        return Math.max(nums[0] * nums[1] * nums[n - 1], nums[n - 1] * nums[n - 2] * nums[n - 3]);
    }
}

54. 螺旋矩阵

思路:

顺时针旋转的方向就是右下左上,所以我们定义一个数组,用来表示顺时针。

int[][] dis = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}};

我们先统计数组的行数和列数,然后从头开始遍历,设定两个参数来判断下一个行数和列数是否超出边界。下一个行数和列数的值用上面dis数组和当前的行数和列数求出。

// 所有的行数和列数
int rows = matrix.length, cols = matrix[0].length;

//  当前的行数和列数
int row = 0, col = 0;

// 下一个row和col,去判断是否越界
int nextRow = row + dis[disIndex][0], nexCol = col + dis[disIndex][1];
if(nextRow<0||nextRow>=rows||nexCol<0||nexCol>=cols||visited[nextRow][nexCol]){
    disIndex = (disIndex + 1) % 4;
}

代码:

class Solution {
    public List<Integer> spiralOrder(int[][] matrix) {
        List<Integer> order = new ArrayList<Integer>();
        if(matrix == null || matrix.length == 0 || matrix[0].length == 0){
            return order;
        }
        int rows = matrix.length, cols = matrix[0].length;
        int[][] dis = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}};
        boolean[][] visited = new boolean[rows][cols];
        int disIndex = 0;
        int total = rows * cols;
        int row = 0, col = 0;
        for(int i = 0; i < total; i++){
            order.add(matrix[row][col]);
            visited[row][col] = true;
            int nextRow = row + dis[disIndex][0], nexCol = col + dis[disIndex][1];
            if(nextRow < 0 || nextRow >= rows || nexCol < 0 || nexCol >= cols || visited[nextRow][nexCol]){
                disIndex = (disIndex + 1) % 4;
            }
            row += dis[disIndex][0];
            col += dis[disIndex][1];
            
        }
        return order;
    }
}

59. 螺旋矩阵 II 

思路:

这个题和上一个差别不大

代码:

class Solution {
    public int[][] generateMatrix(int n) {
        int maxValue = n * n;
        int row = 0, col = 0;
        int[][] res = new int[n][n];
        int[][] dis = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}};
        int disIndex = 0;
        int curValue = 1;
        while(curValue <= maxValue){
            res[row][col] = curValue;
            curValue ++;
            int nexRow = row + dis[disIndex][0], nextCol = col + dis[disIndex][1];
            if(nexRow < 0 || nexRow >= n || nextCol < 0 || nextCol >= n ||res[nexRow][nextCol] != 0){
                disIndex = (disIndex + 1) % 4;
            }
            row = row + dis[disIndex][0];
            col = col + dis[disIndex][1];
        }
        return res;
    }
}

498. 对角线遍历

思路:

我们需要找规律首先是对角线的个数:3行3列的数组有五条对角线所以对角线的个数是m + n - 1(m是行数,n是列数)。

第二个规律:就是遍历的顺序,遍历的结果:

遍历的顺序:


对角线的起始从0开始,所以图中偶数的对角线的遍历是从坐下到右上,奇数的对角线的遍历是从右上到左下。

代码:

class Solution {
    public int[] findDiagonalOrder(int[][] mat) {
        int m = mat.length;
        int n = mat[0].length;
        int[] res = new int[m * n];
        int pos = 0;
        for(int i = 0; i < m + n - 1; i++){
            if(i % 2 == 1){
                int x = i < n ? 0: i - n + 1;
                int y = i < n ? i : n - 1;
                while(x < m && y >= 0){
                    res[pos++] = mat[x][y];
                    y -- ;
                    x ++ ;
                }
            }else{
                int x = i < m ? i: m -1;
                int y = i < m ? 0 : i - m + 1;
                while(x >= 0 && y < n){
                    res[pos++] = mat[x][y];
                    x --;
                    y++;
                }
            }
        }
        return res;
    }
}

  • 16
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值