leetcode之数论与模拟刷题总结1

Posted nuist__NJUPT

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了leetcode之数论与模拟刷题总结1相关的知识,希望对你有一定的参考价值。

leetcode之数论与模拟刷题总结1

1-回文数
题目链接:题目链接戳这里!!!

先来简单题练练手,哈哈

思路1:调库法

class Solution 
    public boolean isPalindrome(int x) 
        if(x<0)
            return false ;
        
        String str1 = String.valueOf(x) ;
        StringBuilder str = new StringBuilder(str1) ;
        str.reverse() ;
        for(int i=0; i<str1.length(); i++)
            if(str.charAt(i) != str1.charAt(i))
                return false ;
            
        
        return true ;
    


思路2:双指针

class Solution 
    public boolean isPalindrome(int x) 
        if(x<0)
            return false ;
        
       String s = String.valueOf(x) ;
       int low = 0, high = s.length()-1 ;
       while(low<=high)
           if(s.charAt(low)!=s.charAt(high))
               return false ;
           
           low ++ ;
           high -- ;
       
       return true ;
    


2-整数翻转
题目链接:题目链接戳这里!!!

思路1:模拟法,整数转换成字符串,从后先前遍历,做翻转处理,对返回的结果做异常处理,如果超过整数范围,捕获异常,并返回0。

class Solution 
    public int reverse(int x) 
        if(x>=-9 && x<=9)
            return x ;
        
        String str = String.valueOf(x) ;
        boolean flag = true ;
        String s = "" ;
        for(int i=str.length()-1; i>=0; i--)
            if(str.charAt(i)=='-')
                s  = str.charAt(i) + s ;
            else if(str.charAt(i)=='0' && flag)
                continue ;
            else
             flag = false ;
            s += str.charAt(i) ;
            
        
        try
        return Integer.parseInt(s) ;
        catch(Exception e)
            return 0 ;
        
    


思路2:数学法

高效率,每次将x的最后一位加到n中,同时将x中的最后以为删除。

class Solution 
    public int reverse(int x) 
       long n = 0 ;
       while(x!=0)
           n = n*10 + x%10 ;
           x /= 10 ;
       
       return (n>Integer.MAX_VALUE || n<Integer.MIN_VALUE) ? 0 : (int)n ;
    


3-罗马数字转整数
题目链接:题目链接戳这里!!!

思路:模拟过程, 从后向前遍历罗马字符换,如果当前字符大于等于上一个字符,则累加当前字符对应的数字,反之累减当前字符对应的数字。

class Solution 
    public int romanToInt(String s) 
        int num1=0, num2 = 0, value = 0;
        for(int i=s.length()-1; i>=0; i--)
            switch(s.charAt(i))
                case 'I' : num1 = 1 ; break ;
                case 'V' : num1 = 5 ; break ;
                case 'X' : num1 = 10 ; break ;
                case 'L' : num1 = 50; break ;
                case 'C' : num1 = 100; break ;
                case 'D' : num1 = 500; break ;
                case 'M' : num1 = 1000; break ;
            
            if(num1>=num2)
                value += num1 ;
            else
                value -= num1 ;
            
            num2 = num1 ;
        
        return value ;
    


4-整数转罗马数字
题目链接:题目链接戳这里!!!
思路:模拟法,从最大的找,找到最大的能表示的罗马数字,则将当前数字减去罗马数字对应得数字,依次将罗马数字添加到字符串后即可。

class Solution 
    public String intToRoman(int num) 
        String [] str = "M","CM","D","CD","C","XC","L","XL","X","IX","V","IV","I" ;
        int [] value = 1000,900,500,400,100,90,50,40,10,9,5,4,1 ;
        String res = "" ;

        for(int i=0; i<13; i++)
            while(num>=value[i])
                num -= value[i] ;
                res += str[i] ;
            
        
        return res;

    


5-逆波兰表达式求值
题目链接:题目链接戳这里!!!

思路:使用栈模拟后缀表达式转换成中缀表达式的过程即可。
如果当前的是数字,则进栈,如果当前的是运算符,则连续出栈两个元素,通过该运算符运算过后,再入栈,如此下去,最后栈中就一个元素,就是我们要求的值。

class Solution 
    public int evalRPN(String[] tokens) 
        Stack<String> stack = new Stack<>() ;
        for(int i=0; i<tokens.length; i++)
            if(!tokens[i].equals("+") && !tokens[i].equals("-") && !tokens[i].equals("*") && !tokens[i].equals("/"))
         stack.push(tokens[i]) ;       
            else
                int a = Integer.parseInt(stack.pop()) ;
                int b = Integer.parseInt(stack.pop()) ;
                int res=0 ;
                switch(tokens[i])
                    case "+" : res = b + a ; break ;
                    case "-" : res = b - a ; break ;
                    case "*" : res = b * a ; break ;
                    case "/" : res = b / a ; break ;
                
                stack.push(String.valueOf(res)) ;
            
        
        return Integer.parseInt(stack.pop()) ;
    


这样写起来看着更舒服

class Solution 
    public int evalRPN(String[] tokens) 
        Stack<Integer> stack = new Stack<>() ;
        for(int i=0; i<tokens.length; i++)
            if(!tokens[i].equals("+") && !tokens[i].equals("-") && !tokens[i].equals("*") && !tokens[i].equals("/"))
         stack.push(Integer.parseInt(tokens[i])) ;       
            else
                int a = stack.pop() ;
                int b = stack.pop() ;
                
                switch(tokens[i])
                    case "+" : stack.push(b+a); break ;
                    case "-" : stack.push(b-a) ; break ;
                    case "*" : stack.push(b*a) ; break ;
                    case "/" : stack.push(b/a); break ;
                
               
            
        
        return stack.pop() ;
    


6-轮转数组
题目链接:题目链接戳这里!!!

思路:用栈来模拟数组轮转过程,每次轮转k%n次,若k%n为0,则不需要轮转.

class Solution 
    public void rotate(int[] nums, int k) 
        Stack<Integer> stack = new Stack<>() ;
        int n = nums.length ;
        for(int i=n-1; i>n-1-(k%n); i--)
            stack.push(nums[i]) ;
        
        for(int i=n-1-(k%n); i>=0; i--)
            nums[i+(k%n)] = nums[i] ; 
        
        for(int i=0; i<(k%n); i++)
            nums[i] = stack.pop() ;
        
    


7-矩形面积
题目链接:题目链接戳这里!!!

思路:主要就算判断两个矩形是否与交集,如果有,则两个矩阵面积和减去交集面积,若无交集,则直接求出两个矩阵的面积和。

class Solution 
    public int computeArea(int ax1, int ay1, int ax2, int ay2, int bx1, int by1, int bx2, int by2) 
       int x1 = Math.max(ax1,bx1) ;
       int y1 = Math.max(ay1,by1) ;
       int x2 = Math.min(ax2,bx2) ;
       int y2 = Math.min(ay2,by2) ;

       if(x1>=x2 || y1>=y2)
           return (ax2-ax1) * (ay2-ay1) + (bx2-bx1) * (by2-by1) ; //无交集
       else
           return (ax2-ax1) * (ay2-ay1) + (bx2-bx1) * (by2-by1)- (x2-x1) * (y2-y1) ;//有交集
       

    


8-丑数
题目链接:题目链接戳这里!!!

思路:循环除以因子,判读最后是否等于1即可。

class Solution 
    public boolean isUgly(int n) 
        if(n<=0)
            return false ;
        
  
        while(n%5==0 || n%3==0 || n%2==0)
            if(n%5==0)
                n /= 5 ;
            else if(n%3==0)
                n /= 3 ;
            else
                n /= 2 ;
            
        
  
        return n == 1 ;
    


写成递归形式也可以的。不过递归的效率不如循环。

class Solution 
    public boolean isUgly(int n) 
    if(n==1)
        return true ;
    
    if(n==0)
        return false ;
    
     if(n%5==0)
         return isUgly(n/5) ;
     
     if(n%3==0)
         return isUgly(n/3) ;
     
     if(n%2==0)
         return isUgly(n/2) ;
     
     return false ;
    


9-单调递增的数字
题目链接:题目链接戳这里!!!

思路:本题首先最容易想到的就是暴力解法,对每个数依次怕判断是否满足要求,这样的话对于数据量大的情况下会超时,这题比较好的做法是用贪心策略,局部最优,则全局最优。

题目要求小于等于N的最大单调递增的整数,那么拿一个两位的数字来举例。

例如:98,一旦出现strNum[i - 1] > strNum[i]的情况(非单调递增),首先想让strNum[i - 1]–,然后strNum[i]给为9,这样这个整数就是89,即小于98的最大的单调递增整数。

这一点如果想清楚了,这道题就好办了。

局部最优:遇到strNum[i - 1] > strNum[i]的情况,让strNum[i - 1]–,然后strNum[i]给为9,可以保证这两位变成最大单调递增整数。

全局最优:得到小于等于N的最大单调递增的整数。

但这里局部最优推出全局最优,还需要其他条件,即遍历顺序,和标记从哪一位开始统一改成9。

此时是从前向后遍历还是从后向前遍历呢?

从前向后遍历的话,遇到strNum[i - 1] > strNum[i]的情况,让strNum[i - 1]减一,但此时如果strNum[i - 1]减一了,可能又小于strNum[i - 2]。

这么说有点抽象,举个例子,数字:332,从前向后遍历的话,那么就把变成了329,此时2又小于了第一位的3了,真正的结果应该是299。

所以从前后向遍历会改变已经遍历过的结果!

那么从后向前遍历,就可以重复利用上次比较得出的结果了,从后向前遍历332的数值变化为:332 -> 329 -> 299

class Solution 
    public int monotoneIncreasingDigits(int n) 
      
     String str = String.valueOf(n) ;
     char [] c = str以上是关于leetcode之数论与模拟刷题总结1的主要内容,如果未能解决你的问题,请参考以下文章

leetcode之模拟刷题总结3

leetcode之哈希表刷题总结1

leetcode之模拟刷题总结2

LeetCode刷题总结之双指针法

LeetCode刷题日记精选例题(解析+代码+链接)

leetcode之分治刷题总结1