LeetCode-数据结构入门-04数组

Day05 数组

最近开始准备工作了,发现自己真的是毫无准备,如果一切能重来的话,我就大二大三暑假出去实习了,现在简历上没有写的,秋招也错过了,如果今年不能出去实习,又找不到合适的计算机相关的工作,那我毕业可能只能先去打工了,唉,但是我并不后悔我放弃考研的决定(题解均来自leetcode网站)。

07 重塑矩阵

2022/2/10
2022/10/11 复习
在 MATLAB 中,有一个非常有用的函数 reshape ,它可以将一个 m x n 矩阵重塑为另一个大小不同(r x c)的新矩阵,但保留其原始数据。
给你一个由二维数组 mat 表示的 m x n 矩阵,以及两个正整数 r 和 c ,分别表示想要的重构的矩阵的行数和列数。
重构后的矩阵需要将原始矩阵的所有元素以相同的 行遍历顺序 填充。
如果具有给定参数的 reshape 操作是可行且合理的,则输出新的重塑矩阵;否则,输出原始矩阵。

(java)
思路:判断是否能输出该矩阵,否则返回原始矩阵;我用了一个笨办法,将传入的矩阵转化为一维数组,再赋值给多维矩阵。

class Solution {
    public int[][] matrixReshape(int[][] mat, int r, int c) {
        int row = mat.length;           //获取行数
        int col = mat[0].length;        //获取列数

        if(row*col != r*c)
        {
            /*
            if((r > row || r == row) && (c > col || c == col))
                return mat;
            return new int[0][0];
            */
            return mat;
        }
            
        int[] storedMat = new int[row*col];
        int count = 0;
        /*
        for(int[] x:mat)
            for(int x1:x)
                storedMat[count++] = x; 
                */
        
        for(int i=0;i<row;i++)
            for(int j=0;j<col;j++)
                storedMat[count++] = mat[i][j];

        //System.out.print(mat[0][1]+" "+mat[1][0]+" "+count);

        for(int i=0;i<count;i++)
            System.out.print(i+" ");

        for(int i=count-1;i>=0;i--)
            System.out.print(i+" ");

        int[][] newMat = new int[r][c];

        for(int i=r-1;i>=0;i--){
            for(int j=c-1;j>=0;j--){
                newMat[i][j] = storedMat[--count];
            }
        }

        return newMat;
    }
}

用时56ms,击败了7.22%用户,可见时间和空间效率都很低。


题解:
相当于一维矩阵的映射,从m行n列到r行c列,满足关系式mn = rc则进行矩阵转换,否则返回原矩阵;
将二维数组 nums 映射成一个一维数组;将这个一维数组映射回 r 行 c 列的二维数组。
(其中通过取模和取余运算完成映射赋值问题)

class Solution {
    public int[][] matrixReshape(int[][] nums, int r, int c) {
        int m = nums.length;
        int n = nums[0].length;
        if (m * n != r * c) {
            return nums;
        }

        int[][] ans = new int[r][c];
        for (int x = 0; x < m * n; ++x) {
            ans[x / c][x % c] = nums[x / n][x % n];
        }
        return ans;
    }
}

08 杨辉三角

2021/12/30
2022/10/11 复习
给定一个非负整数 numRows,生成「杨辉三角」的前 numRows 行。
在「杨辉三角」中,每个数是它左上方和右上方的数的和。

(java)
思路:思路很简单,每一次循环,读取上一次存储的list子列表temp的值,若是首和尾则向子列表中添加1,否则添加temp[i-1]+temp[i]的值,最后将子列表添加到总list中。

class Solution {
    public List<List<Integer>> generate(int numRows) {
        List<List<Integer>> listA = new ArrayList<>();
        List<Integer> listB = new ArrayList<>();

        int count = 1;
        for(int i=0;i<numRows;i++){
            //int[] addList = new int[count];

            //若listA中存在数据
            if(!listA.isEmpty()){   
                //需取上一个子列表进行赋值,清空当前子列表中数据
                listB.clear();
                List<Integer> temp = listA.get(i-1);
                for(int j=0;j<count;j++){
                    if(j==0 || j==count-1)
                        listB.add(1);
                    else{
                        listB.add(temp.get(j-1)+temp.get(j));
                    }
                }
            }else{
                listB.add(1);
            }
            
            //添加list子列表
            listA.add(listB);
            count ++;
        }
        return listA;
    }
}


解答错误,显示list中总是超出下标,但是实际测试,发现temp这个子列表无法通过listA.get(i)语句进行赋值操作。


题解:
(1)每个数字等于上一行的左右两个数字之和;第n行第i个数等于第n-1行的第i-1个数和第i个数之和

class Solution {
    public List<List<Integer>> generate(int numRows) {
        List<List<Integer>> listA = new ArrayList<List<Integer>>();
        for(int i=0;i<numRows;i++){
            //int[] addList = new int[count];
            //若listA中存在数据
            /*if(!listA.isEmpty()){        
                for(int j=0;j<=i;j++){
                    if(j==0 || j==i)
                        listB.add(1);
                    else{
                        //需取上一个子列表进行赋值
                        listB.add(listA.get(i-1).get(j-1)+listA.get(i-1).get(j));
                    }
                }
            }else{
                listB.add(1);
            }*/
            List<Integer> listB = new ArrayList<>();
            for(int j=0;j<=i;j++){
                if(j==0 || j==i)
                    listB.add(1);
                else{
                    //需取上一个子列表进行赋值
                    listB.add(listA.get(i-1).get(j-1)+listA.get(i-1).get(j));
                }
            }
            //添加list子列表
            listA.add(listB);   
        }
        return listA;
    }
}

草稿

改进后的程序如下,依然报错,经过调试后发现,listB中数组在clear()一次后,其基本容量依然为1,第二次add()中,listB中值为[1,null],即add()两次,list作为子对象时,无法扩容
class Solution {
    public List<List<Integer>> generate(int numRows) {
        List<List<Integer>> listA = new ArrayList<>();
        //List<Integer> listB = new ArrayList<>();

        for(int i=0;i<numRows;i++){
            //int[] addList = new int[count];
            List<Integer> listB = new ArrayList<>();
            //若listA中存在数据
            if(!listA.isEmpty()){   
                //需取上一个子列表进行赋值,清空当前子列表中数据
                listB.clear();
                //List<Integer> temp = listA.get(i-1);
                for(int j=0;j<i+1;j++){
                    if(j==0 || j==i)
                        listB.add(1);
                    else{
                        listB.add(listA.get(i-1).get(j-1)+listA.get(i-1).get(j));
                    }
                }
            }else{
                listB.add(1);
            }
            
            //添加list子列表
            listA.add(listB);
  
        }
        return listA;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值