leetCode解题报告5道题(十)

题目一:Valid Number

Validate if a given string is numeric.

Some examples:
"0" => true
" 0.1 " => true
"abc" => false
"1 a" => false
"2e10" => true

Note: It is intended for the problem statement to be ambiguous. You should gather all requirements up front before implementing one.


分析:

这道题目很容易理解,但是主要要考虑到多种情况哈.

下面我们来分析下有哪些情况需要考虑到

1、空格不能出现在数字之间(即一开始我们要消除掉字符串前后的"空格",那么之后如果再出现空格那就不满足题意了)

2、小数点和e最多只能出现一次("." 和"e" (或者"E")), 如:"..2"和"0e1e1"这样的字符串都是不合法的.

3、字符e之前必须有数字,e之后也要有数字, 如: "e1"或者"0e"这样的字符串也不合法

4、正负号要么出现在数字的最前面,要么出现在紧接着e后面("+"或者"-" 只能在“去除空格之后的字符串”的首字母出现 或者 紧跟在"e"的后面出现) 如: "  +123.1  " 或者 "  -12  " 或者 " 0e+6 "或者"  10e-2 "这些都是合法的

5、"e"后面的数字不能是小数(即e之后不能出现小数点)


分析完这些所有的情况,那么我们就可以开始写代码了。看代码理解吧~~~~


AC代码:

public class Solution {
    public boolean isNumber(String s) {
        
        int start = 0;
        int len = s.length();
        int end = len-1;
        boolean flags = false;//直到处理到当前字符的时候是合法(true)还是非法(false)
        boolean exitsE = false;//是否已经存在“e”
        int doin = 0;   //小数点的个数
        //去除前面的空格 ' '
        while (start < len){
            if (s.charAt(start) == ' '){
                start++;
            }else{
                break;
            }
        }
        //去除后面的空格 ' '
        while (end >= 0){
            if (s.charAt(end) == ' '){
                end--;
            }else{
                break;
            }
        }
        //从第一个不是空格的位置开始,到最后一个不是空格的位置
        for (int index=start; index<=end; ++index){
            char c = s.charAt(index);
            //如果开头是"+"或者"-", 那么是可以的!~~~ O(∩_∩)O
            if (index == start && (s.charAt(index) == '-' || s.charAt(index) == '+')){
                continue;
            }
            //如果"+"或者"-"紧跟在"e"或者“E”之后也是可以的!
            if ((s.charAt(index) == '-' || s.charAt(index) == '+') && (s.charAt(index-1) == 'e' || s.charAt(index-1) == 'E')){
                flags = false;
            }else if(!((c >= '0' && c <= '9') || c == '.' || c == 'e' || c == 'E')){
                //除了上面的"+"和"-"之外,如果字符不满足在 0~9 或者 . 或者 e 或者 E中的一个的话,则不合法
                return false;
            }else{
                //如果遇到数字flags则设为合法
                if ((c >= '0' && c <= '9')){
                    flags = true;
                }else if (c == 'e' || c == 'E'){
                    //如果exitsE==true 表示之前的字符串已经出现过 e 或者 "E" 了,这样就有两个e了,不合法
                    if (exitsE){
                        return false;
                    }
                    exitsE = true;
                    
                    //如果flags == true,表示前面有出现过数字
                    if (flags){
                        flags = false;//在把flags设置为false, 用来判断e之后是否还有出现数字
                    }else{
                        return false;
                    }
                }else if (c == '.'){
                    //e后面的数字必须是整数,则如果小数点在e之后的话,直接不合法
                    if (exitsE){
                        return false;
                    }
                    //如果小数点的个数大于1则不合法
                    doin++;
                    if (doin > 1)
                        return false;
                }else{
                    
                }
            }
        }
        return flags;
    }
}


题目二:Jump Game

Given an array of non-negative integers, you are initially positioned at the first index of the array.

Each element in the array represents your maximum jump length at that position.

Determine if you are able to reach the last index.

For example:
A = [2,3,1,1,4], return true.

A = [3,2,1,0,4], return false.

分析:

这道题目的意思挺容易理解的,我们主要讲下解法:

老规矩,我喜欢通过例子来说明解法哈,如果 A=[2, 0, 2, 0, 1]       len = A.length;

我们先从第一个位置A[0]开始,然后我们用一个pos来记录现在第一个位置所能到达的最远距离。

pos = A[0] = 2;

然后我们用一个index (index < len)来记录当前的下标位置,第一个A[0]处理了之后 index++, 

如果index > pos 则表示现在这个index的位置已经是 第一个元素所不能到达的地方了,这样子的话就不可能走到最后一个元素,则返回false

如果index <= pos 则 如果 A[index] + i > pos (第一个元素能走到更远的位置了),更新一下pos的值。


AC代码:

public class Solution {
    public boolean canJump(int[] A) {
        int len = A.length;
        int index = 0;
        int pos = 0;//第一个元素能到的位置
        while (index < len){
            if (pos < index){
                //beyond
                return false;
            }else{
                //before or equals pos
                if (A[index] + index > pos){
                    pos = A[index] + index;
                }
            }
            index++;
        }
        return true;
    }
}


题目三:Jump Game II

 

Given an array of non-negative integers, you are initially positioned at the first index of the array.

Each element in the array represents your maximum jump length at that position.

Your goal is to reach the last index in the minimum number of jumps.

For example:
Given array A = [2,3,1,1,4]

The minimum number of jumps to reach the last index is 2. (Jump 1 step from index 0 to 1, then 3 steps to the last index.)

分析:

这题跟上面的那道题比较像,只不过有点像贪心法,每一步都要走最远的那种情况,所以每一次我们都需要把所有能走到的所有位置先走一遍,看哪个最远。


AC代码:

public class Solution {
    public int jump(int[] A) {
        int len = A.length;
        if (len == 1)
            return 0;
            
        int max = A[0];
        int index = 1;
        int pos = A[0];
        int n = 1;
        
        while (index < len){
            if (pos >= len-1){
                break;//如果pos已经可以到最后一个位置的话,结束
            }
            //before or equals pos
            if (A[index] + index > max && index <= pos){
                max = A[index] + index;//记录最大值
            }
            
            if (index == pos){
                if (max > pos){
                    pos = max;
                    n++;
                }
            }
            index++;
        }
        return n;
    }
}


题目四:Minimum Path Sum

Given a m x n grid filled with non-negative numbers, find a path from top left to bottom right which minimizes the sum of all numbers along its path.

Note: You can only move either down or right at any point in time.

分析:

这道题目可以看做是一个动态规划的题目吧,我们举个例子

如果grid[][]=

1  2  3  4

7  8  1  3

2  5  6  10

我们从右下方的元素开始,往前推

当我们判断到  grid[2][2] == 6 时,它到右下方结点的距离为 6 + 10 = 16, 存入grid[2][2]=16;

当我们判断到 10 上方的那个元素 grid[1][3] == 3时,它到右下方结点的距离为 3 + 10 = 13, 存入grid[1][3]=13;

当判断到 grid[1][2] == 1时, 它到右下方的距离,就是 grid[1][3] 和 grid[2][2]中比较小的那个值 再加上自身的值,即grid[1][2] += min{grid[1][3] (当前元素右边的元素) , grid[2][2] (当前元素下边的元素)};


AC代码:

public class Solution {
    public int minPathSum(int[][] grid) {
        int m = grid.length;
        int n = grid[0].length;
        for (int row=m-1; row>=0; row--){
            for (int col=n-1; col>=0; col--){
                //右边的列的下标
                int colRight = col + 1;
                //下边的行的行标
                int rowDown = row + 1;
                //初始值
                int rowDownValue = Integer.MAX_VALUE;
                int colRightValue = Integer.MAX_VALUE;
                
                //存在行
                if (rowDown < m){
                    rowDownValue = grid[rowDown][col];
                }
                //存在列
                if (colRight < n){
                    colRightValue = grid[row][colRight];
                }
                //取最小
                int min = rowDownValue > colRightValue ? colRightValue : rowDownValue;
                //最小等于Integer.MAX_VALUE则表示没有右边也没有下边元素,即为右下方的那个目标元素
                if (min != Integer.MAX_VALUE){
                    grid[row][col] += min;
                }
            }
        }
        return grid[0][0];
    }
}



题目五:Largest Rectangle in Histogram

Given n non-negative integers representing the histogram's bar height where the width of each bar is 1, find the area of largest rectangle in the histogram.


Above is a histogram where width of each bar is 1, given height = [2,1,5,6,2,3].


The largest rectangle is shown in the shaded area, which has area = 10 unit.

For example,
Given height = [2,1,5,6,2,3],
return 10.

分析:

1、暴力法:

初看题目,很容易给人想到的方法就是暴力法,也就是说对每个 index < len 都找到从index 往左 和 往右,直到height[index] > height[left]  和 height[index] > height[right], 然后 把int temp = height[index] * (right - left + 1) , 如果temp > max, 则更新max的值,但是这样的话一下子就TLE超时了。

TLE代码:

public class Solution {
    public int largestRectangleArea(int[] height) {
        int len = height.length;
        int max = Integer.MIN_VALUE;
        for (int i=0; i<len; ++i){
            int nowHeight = height[i];
            int left=i-1;
            while (left>=0){
                if (height[left] < nowHeight){
                    break;
                }
                --left;
            }
            int right=i+1;
            while (right<len){
                if (height[right] < nowHeight){
                    break;
                }
                ++right;
            }
            
            int allSize = (right-left+1) * nowHeight;
            if (allSize > max){
                max = allSize;
            }
        }
        return max;
    }
}



2、借助辅助栈:

居然暴力法不行,那我们可以知道它主要的时间消耗其实是在寻找左边的left, 和右边的right上面,这样的话有没有什么办法把这块时间节省下来,在我们遍历的过程中确定好left, right的值呢?

我们采用辅助栈( 栈中存放矩形的下标 )来做这道题目可以解决它哈。

算法描述:

1、定义一个空栈

2、遍历数组 index < n

2.1、遍历到index的时候,如果“栈为空”或者height[stack.peek()] <= height[index], 这时候把 index 压入到stack中,并index++

2.2、如果不满足2.1的情况,那么证明栈顶元素p对应的height值比当前index对应的height值来得小,这样的话弹出栈顶元素,并算出以栈顶元素为height所能得到的最大的矩形面积,这时候就是用辅助栈的关键地方了,针对这个情况,它的left位置就是它在栈中的下一个位置(如果没有,则表示left是0,即左边界从0开始),而它的右边界right位置就是当前index的值。

看到这里,肯定迷糊了吧,想想只有当  “栈为空”或者height[stack.peek()] <= height[index] 的时候我们才会把index值压入栈中,也就是说如果把栈从上往下看,必定上面的值对应的height会比下面的大或者相等,这样下面的那个元素对应的值就必定是left的值,同理因为当 当前height[stack.peek()] > height[index] , 我们才进行计算面积的工作,这样子的话这个index就是stack.peek()取到的这个位置对应height 的right右边界咯.


AC代码:

public class Solution {
    public int largestRectangleArea(int[] height) {
        int len = height.length;
        if (len == 0)
            return 0;
        int max = Integer.MIN_VALUE;
        Stack<Integer> stack = new Stack<Integer>();
        int index = 0;
        while (index < len){
            if (stack.empty() || height[(int)stack.peek()] <= height[index]){
                stack.push(index);
                index++;//这里才有++哦!
            }else{
                //计算面积
                int popIndex = (int)stack.pop();
                int allWidth = stack.empty() ? index : index-((int)stack.peek())-1;
                int tempValue = height[popIndex] * allWidth;
                if (tempValue > max){
                    max = tempValue;
                }
            }
        }
        //right边界都为len
        while (!stack.empty()){
            int popIndex = (int)stack.pop();
            int allWidth = stack.empty() ? len : len-((int)stack.peek())-1;
            int tempValue = height[popIndex] * allWidth;
            if (tempValue > max){
                max = tempValue;
            }
        }
        return max;
    }
}


已标记关键词 清除标记
DirectX修复工具(DirectX Repair)是一款系统级工具软件,简便易用。本程序为绿色版,无需安装,可直接运行。 本程序的主要功能是检测当前系统的DirectX状态,如果发现异常则进行修复。程序主要针对0xc000007b问设计,可以完美修复该问。本程序中包含了最新版的DirectX redist(Jun2010),并且全部DX文件都有Microsoft的数字签名,安全放心。 本程序为了应对一般电脑用户的使用,采用了易用的一键式设计,只要点击主界面上的“检测并修复”按钮,程序就会自动完成校验、检测、下载、修复以及注册的全部功能,无需用户的介入,大大降低了使用难度。在常规修复过程中,程序还会自动检测DirectX加速状态,在异常时给予用户相应提示。 本程序适用于多个操作系统,如Windows XP(需先安装.NET 2.0,详情请参阅“致Windows XP用户.txt”文件)、Windows Vista、Windows 7、Windows 8、Windows 8.1、Windows 8.1 Update、Windows 10,同时兼容32位操作系统和64位操作系统。本程序会根据系统的不同,自动调整任务模式,无需用户进行设置。 本程序的V4.0版分为标准版、增强版以及在线修复版。所有版本都支持修复DirectX的功能,而增强版则额外支持修复c++的功能。在线修复版功能与标准版相同,但其所需的数据包需要在修复时自动下载。各个版本之间,主程序完全相同,只是其配套使用的数据包不同。因此,标准版和在线修复版可以通过补全扩展包的形式成为增强版。本程序自V3.5版起,自带扩展功能。只要在主界面的“工具”菜单下打开“选项”对话框,找到“扩展”标签,点击其中的“开始扩展”按钮即可。扩展过程需要Internet连接,扩展成功后新的数据包可自动生效。扩展用时根据网络速度不同而不同,最快仅需数秒,最慢需要数分钟,烦请耐心等待。如扩展失败,可点击“扩展”界面左上角小锁图标切换为加密连接,即可很大程度上避免因防火墙或其他原因导致的连接失败。 本程序自V2.0版起采用全新的底层程序架构,使用了异步多线程编程技术,使得检测、下载、修复单独进行,互不干扰,快速如飞。新程序更改了自我校验方式,因此使用新版本的程序时不会再出现自我校验失败的错误;但并非取消自我校验,因此程序安全性与之前版本相同,并未降低。 程序有更新系统c++功能。由于绝大多数软件运行时需要c++的支持,并且c++的异常也会导致0xc000007b错误,因此程序在检测修复的同时,也会根据需要更新系统中的c++组件。自V3.2版本开始使用了全新的c++扩展包,可以大幅提高工业软件修复成功的概率。修复c++的功能仅限于增强版,标准版及在线修复版在系统c++异常时(非丢失时)会提示用户使用增强版进行修复。除常规修复外,新版程序还支持C++强力修复功能。当常规修复无效时,可以到本程序的选项界面内开启强力修复功能,可大幅提高修复成功率。请注意,请仅在常规修复无效时再使用此功能。 程序有两种窗口样式。正常模式即默认样式,适合绝大多数用户使用。另有一种简约模式,此时窗口将只显示最基本的内容,修复会自动进行,修复完成10秒钟后会自动退出。该窗口样式可以使修复工作变得更加简单快速,同时方便其他软件、游戏将本程序内嵌,即可进行无需人工参与的快速修复。开启简约模式的方法是:打开程序所在目录下的“Settings.ini”文件(如果没有可以自己创建),将其中的“FormStyle”一项的值改为“Simple”并保存即可。 新版程序支持命令行运行模式。在命令行中调用本程序,可以在路径后直接添加命令进行相应的设置。常见的命令有7类,分别是设置语言的命令、设置窗口模式的命令,设置安全级别的命令、开启强力修复的命令、设置c++修复模式的命令、控制Direct加速的命令、显示版权信息的命令。具体命令名称可以通过“/help”或“/?”进行查询。 程序有高级筛选功能,开启该功能后用户可以自主选择要修复的文件,避免了其他不必要的修复工作。同时,也支持通过文件进行辅助筛选,只要在程序目录下建立“Filter.dat”文件,其中的每一行写一个需要修复文件的序号即可。该功能仅针对高级用户使用,并且必须在正常窗口模式下才有效(简约模式时无效)。 本程序有自动记录日志功能,可以记录每一次检测修复结果,方便在出现问时,及时分析和查找原因,以便找到解决办法。 程序的“选项”对话框中包含了7项高级功能。点击"常规”选项卡可以调整程序的基本运行情况,包括日志记录、安全级别控制、调试模式开启等。只有开启调试模式后才能在C
相关推荐
<p> <b><span style="background-color:#FFE500;">【超实用课程内容】</span></b> </p> <p> <br /> </p> <p> <br /> </p> <p> 本课程内容包含讲解<span>解读Nginx的基础知识,</span><span>解读Nginx的核心知识、带领学员进行</span>高并发环境下的Nginx性能优化实战,让学生能够快速将所学融合到企业应用中。 </p> <p> <br /> </p> <p style="font-family:Helvetica;color:#3A4151;font-size:14px;background-color:#FFFFFF;"> <b><br /> </b> </p> <p style="font-family:Helvetica;color:#3A4151;font-size:14px;background-color:#FFFFFF;"> <b><span style="background-color:#FFE500;">【课程如何观看?】</span></b> </p> <p style="font-family:Helvetica;color:#3A4151;font-size:14px;background-color:#FFFFFF;"> PC端:<a href="https://edu.csdn.net/course/detail/26277"><span id="__kindeditor_bookmark_start_21__"></span></a><a href="https://edu.csdn.net/course/detail/27216">https://edu.csdn.net/course/detail/27216</a> </p> <p style="font-family:Helvetica;color:#3A4151;font-size:14px;background-color:#FFFFFF;"> 移动端:CSDN 学院APP(注意不是CSDN APP哦) </p> <p style="font-family:Helvetica;color:#3A4151;font-size:14px;background-color:#FFFFFF;"> 本课程为录播课,课程永久有效观看时长,大家可以抓紧时间学习后一起讨论哦~ </p> <p style="font-family:"color:#3A4151;font-size:14px;background-color:#FFFFFF;"> <br /> </p> <p class="ql-long-24357476" style="font-family:"color:#3A4151;font-size:14px;background-color:#FFFFFF;"> <strong><span style="background-color:#FFE500;">【学员专享增值服务】</span></strong> </p> <p class="ql-long-24357476" style="font-family:"color:#3A4151;font-size:14px;background-color:#FFFFFF;"> <b>源码开放</b> </p> <p class="ql-long-24357476" style="font-family:"color:#3A4151;font-size:14px;background-color:#FFFFFF;"> 课件、课程案例代码完全开放给你,你可以根据所学知识,自行修改、优化 </p> <p class="ql-long-24357476" style="font-family:"color:#3A4151;font-size:14px;background-color:#FFFFFF;"> 下载方式:电脑登录<a href="https://edu.csdn.net/course/detail/26277"></a><a href="https://edu.csdn.net/course/detail/27216">https://edu.csdn.net/course/detail/27216</a>,播放页面右侧点击课件进行资料打包下载 </p> <p> <br /> </p> <p> <br /> </p> <p> <br /> </p>
©️2020 CSDN 皮肤主题: 酷酷鲨 设计师:CSDN官方博客 返回首页