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的主要内容,如果未能解决你的问题,请参考以下文章