力扣爆刷第162天之TOP100五连刷76-80(最小路径和、最长公共前缀、最长连续序列)

力扣爆刷第162天之TOP100五连刷76-80(最小路径和、最长公共前缀、最长连续序列)

一、64. 最小路径和

题目链接:https://leetcode.cn/problems/minimum-path-sum/description/
思路:每次只能向下或向右移动一步,求最小路径和,很经典的一道动态规划题,定义dp[i][j]表示,抵达nums[i][j]时的最小路径和,那么根据定义,要想抵达nums[i][j]这个位置,就得从nums[i-1][j]或者nums[i][j-1]的位置出发,而这两个位置对应的最小路径和即为dp[i-1][j]或者dp[i][j-1],故而dp[i][j] = min(dp[i-1][j], dp[i][j-1]) + nums[i][j]。
另外就是可以节省一下空间,把二维数组替换成一维数组。那么就要注意初始化,以及每一行开始的位置。
在这里插入图片描述

class Solution {
    public int minPathSum(int[][] grid) {
        int m = grid.length, n = grid[0].length;
        int[] dp = new int[n+1];
        Arrays.fill(dp, Integer.MAX_VALUE);
        dp[1] = 0;
        for(int i = 0; i < m; i++) {
            for(int j = 0; j < n; j++) {
                dp[j+1] = Math.min(dp[j], dp[j+1]) + grid[i][j];
            }
        }
        return dp[n];
    }
}

二、221. 最大正方形

题目链接:https://leetcode.cn/problems/maximal-square/description/
思路:矩阵内包含0或者1,求全为1的最大正方形,其实可以把题目理解为不为零的正方形的边长的计算,定义dp[i][j]表示以nums[i][j]为右下角的不为0的正方形的最大边长。那么根据定义可以得到推导关系,如果nums[i][j]不为0,那么以他为右下角的不为0的最长正方形边长,应该依赖于该位置的左方、上方、左上方的最小边长+1,。如这3个位置记录的边长为1,1,0,那么此处为0+1,如果是1,1,1,那么此处为1+1。如果为1,2,1,那么此处为1+1.
故而,dp[i][j] = Math.min(dp[i-1][j-1], Math.min(dp[i-1][j], dp[i][j-1])) + 1;
在这里插入图片描述

class Solution {
    public int maximalSquare(char[][] matrix) {
        int m = matrix.length, n = matrix[0].length;
        int[][] dp = new int[m][n];
        int max = 0;
        for(int i = 0; i < m; i++) {
            for(int j =0; j < n; j++) {
                if(matrix[i][j] == '0') continue;
                else if(i == 0 || j == 0) dp[i][j] = 1;
                else dp[i][j] = Math.min(dp[i-1][j-1], Math.min(dp[i-1][j], dp[i][j-1])) + 1;
                max = Math.max(max, dp[i][j]);
            }
        }
        return max * max;
    }
}

三、162. 寻找峰值

题目链接:https://leetcode.cn/problems/find-peak-element/description/
思路:让在数组中寻找峰值,所谓峰值即1,2,1其中2就是峰值,本身来说好找,遍历一遍即可,但是题目要求在O(logn)的时间复杂度完成,那么一般只要是要求logn,那么基本上就得是划分区间二分之类的,才能达到,心里要有这个意识。
既然知道了需要划分区间,那么区间该如何划分呢?其实很简单就是二分划分,二分查找,中间值如果满足峰值条件就直接返回,如果不满足就再次划分区间去各自的区间内进行重复的寻找即可。

class Solution {
    int index = -1;
    public int findPeakElement(int[] nums) {
        if(nums.length == 1) return 0;
        findMax(nums, 0, nums.length-1);
        return index;
    }
    
    void findMax(int[] nums, int left, int right) {
        if(left > right || index != -1) return;
        int mid = left + (right - left) / 2;
        if(mid == 0) {
            if(nums[mid] > nums[mid+1]) {
                index = mid;
                return;
            }
        }else if(mid == nums.length-1) {
            if(nums[mid] > nums[mid-1]) {
                index = mid;
                return;
            }
        }else if(nums[mid] > nums[mid-1] && nums[mid] > nums[mid+1]) {
            index = mid;
            return;
        }
        findMax(nums, left, mid-1);
        findMax(nums, mid+1, right);
    }
}

四、14. 最长公共前缀

题目链接:https://leetcode.cn/problems/longest-common-prefix/description/
思路:求最长公共前缀,这个直接遍历就可以,用第一个字符串中的每一个字符去遍历剩下每一个字符串中的字符,只要出现长度超界或者不等,就算抵达终点位置了,直接返回即可。

class Solution {
    public String longestCommonPrefix(String[] strs) {
        if(strs.length == 1) return strs[0];
        StringBuilder sb = new StringBuilder();
        for(int i = 0; i < strs[0].length(); i++) {
            for(int j = 1; j < strs.length; j++) {
                if(i >= strs[j].length() || strs[0].charAt(i) != strs[j].charAt(i)) return sb.toString();
            }
            sb.append(strs[0].charAt(i));
        }
        return sb.toString();
    }
}


五、128. 最长连续序列

题目链接:https://leetcode.cn/problems/longest-consecutive-sequence/description/
思路:有一个无序序列,求其中的元素能够排列组合成的最长连续序列,也就是如4,5,3,2,1,最长为1,2,3,4,5最长连续长度为5。
这种无序的请求可以考虑使用set添加元素,都添加之后遍历set,如果当前元素-1不存在于set之中,说明这个元素可能是一个连续序列的开头,所以就从此处开始,不断的+1,然后判断是否在set中,这样就可以求出最长连续序列。

class Solution {
    public int longestConsecutive(int[] nums) {
        Set<Integer> set = new HashSet<>();
        for(int i : nums) set.add(i);
        int max = 0;
        for(int i : set) {
            if(!set.contains(i-1)) {
                int t = 0;
                while(set.contains(i)) {
                    i++;
                    t++;
                }
                max = Math.max(max, t);
            }
        }
        return max;
    }
}
USB启动制作向导可以将您的U、MP3、移动硬制作成为USB-HDD启动制作启动后不影响您的设备正常使用,MP3仍可照常听歌。程序操作简单,无需专业知识及其他工具,几分钟即可制作完成。工具内置了DOS工具及WINPE微型操作系统,便于日常紧急维护。    USB启动制作向导操作说明:  U/MP3:必须先格式化为HDD模式,激活分区使其可以引导,再写入文件。  移动硬:本身就是HDD模式,如果已经有激活分区,直接写入文件即可。  注:格式化将清除所有数据,请实现备份好您的文件。本程序至少需要U空间80M。    USB启动制作向导系统说明:  WINPE(月光森林)采用NT引导模式,避免个别机器不兼容GRUB引导而无法进入PE。  GRUB版本为0.4.4,DOS工具为MAXDOS7.1,支持网刻,带PQ\DM\DISKGEN等DOS工具。  WINPE支持网络、带万能显卡驱动,支持安装VISTA\WIN7。   USB启动制作向导报毒说明:  由于含有查看系统密码的软件,另有部分软件为破解版,可能杀毒软件会误报。  请不必担心误报现象,本程序在制作时是经过了严格杀毒的,请放心使用。  如果usb启动程序被杀毒软件拦截而无法安装到U,可先关闭杀毒软件,待安装完毕再打开杀毒软件。  若无法信任我们为您提供的PE工具,可删除被误报的小工具,自行寻找绿色版添加到UPE内。   USB启动制作向导安装图解:
软件介绍: 深度U助手深度u启动制作工具,具有以下功能: 基本功能除了包括U读写测速外,还有制作USB-HDD启动,辅助修复文件系统等高级功能。在USB-HDD格式化那里继续沿用DEEPIN前续版本的HP低格工具,自己开发了替代DSPTW的相应功能,目标是--在后续版本中实现原创的HP低格工具的功能,争取做到100% DeepIn原创! 制作启动(B) USB-HDD格式化(F)本功能延续前续老大完成的版本 ,将U格式化为USB-HDD模式。制作USB-PE启动(P)PE启动文件包,请另行下载。将所有启动文件即root文件夹完整拷贝至本软件根目录的root文件夹下,然后执行本功能即可。请确认U可读写和必要的使用空间。性能测试(T) 小文件读/写测试(S)默认进行100个32K小文件读写测试,运行过程中,请勿中断,防止产生测试临时文件。大文件读/写测试(B)默认进行1个50M大文件读写测试,运行过程中,请勿中断,防止产生测试临时文件。自动进行所有测试(A)默认首先进行小文件测试,然后进行大文件读写测试,运行过程中,请勿中断,防止产生测试临时文件。高级功能:显示MBR信息(S)在信息文本框里显示MBR信息,便于大家观察UMBR内容。磁扫描(C)可以进行坏扇区检测,并探测真实容量--针对U容量变大的问题。查找分区表扇区(P)对有分区表标志的扇区的扫描,但是没有加入其链关系。绝对扇区操作(G)可以对U绝对扇区读写,目前开放读取逻辑线性扇区,从MBR开始计数0。请谨慎操作,清空和修改都将会把内容写入磁。在输入修改内容时,请使用大写字符,2位,表示一个字节。清除所有内容(E)将磁所有扇区清0,请大家谨慎操作!!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

当年拼却醉颜红

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值