暴躁算法(剑指系列)-每日一练

2022.4.14

1672. 最富有客户的资产总量

难度 简单

​ 给你一个 m x n 的整数网格 accounts ,其中 accounts[i][j] 是第 i 位客户在第 j 家银行托管的资产数量。返回最富有客户所拥有的 资产总量

客户的 资产总量 就是他们在各家银行托管的资产数量之和。最富有客户就是 资产总量 最大的客户。

思路:

  • 建立一个数组,存放每一个人的总资产。最后返回Math.max
  • 或者,直接遍历,不另外建立数组。
public int maximumWealth(int[][] accounts) {
    //钱最大的数量
        int max=0;
    //单个人的钱
        int count;
    //遍历人
        for(int i=0;i< accounts.length;i++){
            count=0;
            //遍历单个人的所有银行
            for(int j =0;j< accounts[0].length;j++){
                count+=accounts[i][j];
            }
            max=count>max?count:max;
        }
        return max;
    }

执行结果:

通过

执行用时:0 ms, 在所有 Java 提交中击败了100.00%的用户

内存消耗:40.8 MB, 在所有 Java 提交中击败了44.65%的用户

通过测试用例:34 / 34

剑指 Offer 03. 数组中重复的数字

难度简单807

找出数组中重复的数字。

​ 在一个长度为 n 的数组 nums 里的所有数字都在 0~n-1 的范围内。数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次。请找出数组中任意一个重复的数字。

思路1:

排序+遍历,一旦找到重复的值,立刻返回。

排序可以使用指针+原地排序数组(适用于节约空间优先的场景)

public int findRepeatNumber(int[] nums) {
            Arrays.sort(nums);
            for(int i=0;i<nums.length-1;i++){
                if(nums[i]==nums[i+1]){
                    return nums[i];
                }
            }
            return 0;
    }

感觉写的很潇洒。emmmm效率不高

执行用时:4 ms, 在所有 Java 提交中击败了57.74%的用户

内存消耗:49 MB, 在所有 Java 提交中击败了44.60%的用户

思路二:

建立一个set,遍历一次,如果一个数字已经在set中,就返回,否则加入set

public int findRepeatNumber(int[] nums) {
            HashSet<Integer> set  = new HashSet<>();
            for(int i=0;i<nums.length;i++) {
                if(set.contains(nums[i])){
                    return nums[i];
                }
                set.add(nums[i]);
            }
            return 0;}

还不如之前。

思路三:在一个长度为 n 的数组 nums 里的所有数字都在 0~n-1 的范围内

所以,索引与值,是一对多的关系:

因而,就能通过索引映射对应的值,起到与字典等价的作用。

遍历中,第一次遇到数字 xx 时,将其交换至索引 xx 处;

而当第二次遇到数字 xx 时,一定有 nums[x] = xnums[x]=x ,此时即可得到一组重复数字。

public int findRepeatNumber(int[] nums) {
    //初始化遍历指针
        int i = 0;
        while(i < nums.length) {
            //数字x就在索引x处,不用处理
            if(nums[i] == i) {
                i++;
                continue;
            }
            //遍历的时候,遇到数字x,在索引y处,想把他放回nums[x],结果nums[x]这地方已经有一个x了。
      		//说明什么
            //有重复数字出现,直接返回
            if(nums[nums[i]] == nums[i]) return nums[i];
            
            //不然就交换到正确的位置
            int tmp = nums[i];
            nums[i] = nums[tmp];
            nums[tmp] = tmp;
        }
        return -1;
    }

结果:

执行用时:0 ms, 在所有 Java 提交中击败了100.00%的用户

内存消耗:48.3 MB, 在所有 Java 提交中击败了82.30%的用户

剑指 Offer 04. 二维数组中的查找

难度中等645

在一个 n * m 的二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个高效的函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。

思路一:直接暴力两层循环。

面试用暴力法的话,面试官:“今天就到这里吧🐒”

啊哈哈哈哈哈哈

public boolean findNumberIn2DArray(int[][] matrix, int target) {
        if (matrix == null || matrix.length == 0 || matrix[0].length == 0) {
            return false;
        }
    //行与列
        int rows = matrix.length, columns = matrix[0].length;
    //两层循环
        for (int i = 0; i < rows; i++) {
            for (int j = 0; j < columns; j++) {
                if (matrix[i][j] == target) {
                    return true;
                }
            }
        }
        return false;
    }

思路二:

从右上作为初始点,进行线性查找。

因为右上角向下,所有元素大于本身,向左走所有数字小于自身。

当 target > num, 向下移动数值变大 r += 1
当 target < num, 向左移动数值变小 c -= 1
始终能存在: 向左变小和向下变大的规律移动

 public boolean findNumberIn2DArray(int[][] matrix, int target) {
        //注意特殊情况
        if (matrix == null || matrix.length == 0 || matrix[0].length == 0){
            return false;
        }
     //初始化矩阵的长和宽
        int len = matrix.length;
        int wid = matrix[0].length;
     //初始话右上角坐标
        int a = 0,b=wid-1;
        while(a<len && b>=0){
            if(matrix[a][b]==target){
                return  true;
            }
            if(matrix[a][b]<target){
                a++;
            }else{
                b--;
            }
        }
        return false;
    }

思路三:

深搜

public static boolean findNumberIn2DArray(int[][] matrix, int target) {
       return dfs(0,0,matrix,target);
    }

    private static boolean dfs(int i, int j,int[][] matrix, int target) {
        //超出索引就停止
        if(i>=matrix.length || j>=matrix[0].length){
            return false;
        }else{
            //找到了就停止
        if(matrix[i][j]==target){
            return true;
        }}
        //如果target大于现在的位置,就向右向下试探。否则返回false
        if(matrix[i][j]<target){
        if(dfs(i+1,j,matrix,target)||
         dfs(i,j+1,matrix,target)){
             return true;
         }
        }
        return false;
    }

用例对了,但是超过时间限制。

算了,就当小写怡情。

最后来一个简单的怡怡情

剑指 Offer 05. 替换空格

难度简单

请实现一个函数,把字符串 s 中的每个空格替换成"%20"

第一种:老老实实遍历

public String replaceSpace(String s) {
        StringBuilder sb = new StringBuilder();
        for(int i = 0 ; i < s.length(); i++){
            char c = s.charAt(i);
            if(c == ' ') sb.append("%20");
            else sb.append(c);
        }
        return sb.toString();
    }

第二种:库函数

public String replaceSpace(String s) {
        return s.replace(" ","%20");
    }

执行结果:

通过

执行用时:0 ms, 在所有 Java 提交中击败了100.00%的用户

内存消耗:39.5 MB, 在所有 Java 提交中击败了20.06%的用户

简单粗暴。。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值