阿里笔试325

我没参赛,看你们的题目,不知道写的代码能不能AC
第一题用dp[n][3] 表示第i列选择第j个值能得到的最小绝对值差的和。
public static void minN(int[][] nums){
        int c = nums[0].length;
        int[][] dp = new int[c][3];
        // 第i列
        for (int i = 1; i < c; i++) {
            //本次选择第j个数,第j行
            for (int j = 0; j < 3; j++) {
                //前一次选择第k个数的最小值
                for (int k = 0; k < 3; k++) {
                    //没填充大值,用第一个数填充一下
                    if (k==0){
                        dp[i][j] = Math.abs(nums[j][i]-nums[k][i-1])+dp[i-1][k];
                    }else {
                        dp[i][j] = Math.min(Math.abs(nums[j][i]-nums[k][i-1])+dp[i-1][k], dp[i][j]);
                    }
                }
            }
        }
        System.out.println(Math.min(dp[c-1][0], Math.min(dp[c-1][1],dp[c-1][2])));
    }


第二题就是循环按行列补充,直到没有新的值出现,没有检查该位置确实为0的情况,其实只需要看对应行列是否修改过就行。
public static void solve(int[][] nums){
        int r = nums.length, c = nums[0].length;
        boolean[] flag = new boolean[r+c];
        while (rowSolve(nums,flag)||colunm(nums,flag)){

        }
    }

    public static boolean rowSolve(int[][] nums, boolean[]flag){
        int r = nums.length, c = nums[0].length;
        boolean f = false;
        for (int i = 0; i < r; i++) {
            if (!flag[i]){
                int[] pre = new int[2];
                for (int j = 0; j < c; j++) {
                    if (nums[i][j]!=0&&pre[1]!=0){
                        int dif = (nums[i][j] - pre[1])/(j - pre[0]);
                        for (int k = j+1; k < c; k++) {
                            nums[i][k] = nums[i][k-1] + dif;
                        }
                        for (int k = j-1; k >= 0; k--) {
                            nums[i][k] = nums[i][k+1] - dif;
                        }
                        flag[i] = true;
                        f = true;
                        break;
                    }else if (nums[i][j]!=0){
                        pre[0] = j;
                        pre[1] = nums[i][j];
                    }
                }
            }
        }
        return f;
    }


    public static boolean colunm(int[][] nums, boolean[] flag){
        int r = nums.length, c = nums[0].length;
        boolean f = false;
        for (int j = 0; j < c; j++) {
            if (!flag[r+j]){
                int[]pre = new int[2];
                for (int i = 0; i < r; i++) {
                    if (nums[i][j]!=0&&pre[1]!=0){
                        int dif = (nums[i][j] - pre[1])/(i - pre[0]);
                        for (int k = i+1; k < r; k++) {
                            nums[k][j] = nums[k-1][j]+dif;
                        }
                        for (int k = i-1; k >= 0; k--) {
                            nums[k][j] = nums[k+1][j]-dif;
                        }

                        f = true;
                        flag[r+j]=true;
                        break;
                    }else if (nums[i][j]!=0){
                        pre[0] = i;
                        pre[1] = nums[i][j];
                    }
                }
            }
        }
        return f;
    }


#阿里笔试##阿里巴巴##笔试题目#
全部评论
第一题听说要long long
点赞 回复 分享
发布于 2020-03-25 18:26

相关推荐

不愿透露姓名的神秘牛友
昨天 10:11
点赞 评论 收藏
分享
不愿透露姓名的神秘牛友
08-08 18:20
职场水母:这题思路是什么,我目前想的一个暴力方法就是先把这个链表遍历一遍,用哈希表存储出现次数,然后再根据哈希表来一个一个删除节点,
点赞 评论 收藏
分享
09-17 17:33
门头沟学院 Java
阿里面试一直在聊天是不是就是kpi了
offer收割机jo...:应该不是KPI,因为好多人阿里简历都过不去
我的秋招日记
点赞 评论 收藏
分享
评论
点赞
5
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务