leetcode之递归刷题总结1
1-递归乘法
题目链接:
思路:让B-1乘A并递归下去,递归的结果加上A,就是B乘A。
AC代码如下:
class Solution {
public int multiply(int A, int B) {
if(B==0){
return 0 ;
}
return A + multiply(A,B-1) ;
}
}
2-预测赢家
题目链接:题目链接戳这里!!!
思路:如果是偶数个数字,先抓的一定赢,要是奇数个,则递归求出A选择的值-B选择的值得到的最大值。大于等于0,则A赢,反之B赢。
AC代码如下:
class Solution {
public boolean PredictTheWinner(int[] nums) {
if((nums.length&1)==0){
return true ;
}
return f(nums, 0, nums.length-1)>=0 ;
}
public int f(int [] nums, int l, int r){
if(l==r){
return nums[l] ;
}
int left = nums[l]-f(nums,l+1,r) ;
int right = nums[r]-f(nums,l,r-1) ;
return Math.max(left, right) ;
}
}
3-斐波那契数列
题目链接:题目链接戳这里!!!
AC代码如下:
class Solution {
public int fib(int n) {
if(n==0){
return 0 ;
}
if(n==1){
return 1 ;
}
return fib(n-1)+fib(n-2) ;
}
}
4- 2的幂
题目链接:题目链接戳这里!!!
AC代码如下:
通过位运算递归实现:
class Solution {
public boolean isPowerOfTwo(int n) {
if(n<=0){
return false ;
}
return ((n-1) & n) ==0 ;
}
}
不停的除以2,判断是不是不等于1的奇数也可以。
class Solution {
public boolean isPowerOfTwo(int n) {
if(n<=0){
return false ;
}
if(n==1){
return true ;
}
if((n&1)==1){
return false ;
}
return isPowerOfTwo(n/2) ;
}
}
5-找出游戏的获胜者
题目链接:题目链接戳这里!!!!+
思路:约瑟夫环问题,记住递推表达式就可以。
AC代码如下:
class Solution {
public int findTheWinner(int n, int k) {
if(n==1){
return n ;
}
return (findTheWinner(n-1, k) + k-1)%n + 1 ;
}
}
非递归代码如下:
class Solution {
public int findTheWinner(int n, int k) {
int s=1 ;
for(int i=2; i<=n; i++){
s = (s+k-1)%i+1;
}
return s ;
}
}
6-翻转字符串暖
题目链接:题目链接戳这里!!!
基础题,就是双指针,要求不开辟额外的存储空间
AC代码如下:
class Solution {
public void reverseString(char[] s) {
int l = 0;
int r = s.length-1 ;
while(l<r){
char temp = s[l] ;
s[l] = s[r] ;
s[r] = temp ;
l++;
r--;
}
}
}
7. 3的幂
题目链接:题目链接戳这里!!!
思路:不停除3递归,如果不能对3取余,则不是3的幂,如果一直能递归到1,则是3的幂。
class Solution {
public boolean isPowerOfThree(int n) {
if(n<=0){
return false ;
}
if(n==1){
return true ;
}
if(n%3!=0){
return false ;
}
return isPowerOfThree(n/3) ;
}
}
8. 4的幂
题目链接:题目链接戳这里!!!
思路和上题一样,不再赘述!
class Solution {
public boolean isPowerOfFour(int n) {
if(n<=0){
return false ;
}
if(n==1){
return true ;
}
if(n%4!=0){
return false ;
}
return isPowerOfFour(n/4) ;
}
}
9.统计好数字的数目
题目链接:题目链接戳这里!!!
思路:这题用到了快速幂,就是5的奇数次放乘4的偶数次方,但是直接算次方算不出来的,必须用快速幂。
AC代码如下:
class Solution {
public int countGoodNumbers(long n) {
long mod = 1000000007;
long even = n / 2 ;
long odd = n / 2 ;
if((n&1)==1){
odd ++ ;
}
long ans1 = pow(5,odd,mod) ;
long ans2 = pow(4,even,mod) ;
return (int)((ans1*ans2)%mod) ;
}
public long pow(long base, long x, long mod){
long ans = 1 ;
while(x != 0){
if((x&1)==1){
ans = (ans*base)%mod;
}
base = base * base %mod;
x = x / 2 ;
}
return ans ;
}
}
10-2出现的次数
题目链接:题目链接戳这里!!!
这题最容易想到的是转换成字符串,暴力统计2的个数,不过这种大数会超时,AC不了。
思路:
首先2的个数就是数字n的各个…千,百,十,个位上的2的个数之和。
举例:
1、当n的第一个数字为1时,以n = 168为例。
168中2的个数 = 0~99中2的个数 + 100~168中2的个数
容易看出100~168中2的个数 = 0~68中2的个数
所以:168中2的个数 = 0~99中2的个数 + 0~68中2的个数
2、当n的第一个数字为2时,以n = 268为例。
268中2的个数 = 0~199中2的个数 + 200~268中2的个数
200~268中2的个数 = 百位上2的个数 + 十位上2的个数 + 个位上2的个数
=69(百位) + 0~68中2的个数(十位 + 个位)
所以:268中2的个数 = 0~199中2的个数 + 0~68中2的个数 + 69
3、当n的第一个数字大于2时,以n = 468为例。
只有在200~299时n的百位上才有2,共100个
0-99,100-199,200-299,300-399 中十位上2的个数都相同
400~468中2的个数 = 0 ~ 68中2的个数
所以n = 468中2的个数 = 100 + 4 * 0~99中2的个数 + 0~68中2的个数
AC代码如下:
class Solution {
public int numberOf2sInRange(int n) {
String s = String.valueOf(n) ;
int len = s.length() ;
if(n<2){
return 0 ;
}
if(n<12){
return 1 ;
}
if(n<20){ //该递归只能处理两位数以上的
return 2 ;
}
int first = (s.charAt(0) - '0') ;
int power = (int)Math.pow(10,len-1) ;
int last = Integer.parseInt(s.substring(1));
if(first==1){
return numberOf2sInRange(power-1) + numberOf2sInRange(last) ;
}else if(first==2){
return numberOf2sInRange(2*power-1)+numberOf2sInRange(last) + last+1 ;
}else{
return power + first*numberOf2sInRange(power-1)+numberOf2sInRange(last) ;
}
}
}
11-数字1的个数
题目链接:题目链接戳这里!!!
思路:这题和上题思路一样,还稍微简单一点。
我们判断首位是不是1,然后递归下去即可。
若首位是1,例如168
则168中1的个数=0-99中1的个数+100-168中1的个数
也就是等于0-99中1的个数+百位上1的个数69+0-68中1的个数
若首位不是1,例如268
则268中1的个数=百位上1的个数100+2倍的0-99上1的个数+0-68中1的个数
AC代码如下:
class Solution {
public int countDigitOne(int n) {
String s = String.valueOf(n) ;
int len = s.length();
if(n<1){
return 0 ;
}
if(n<10){
return 1 ;
}
int power = (int)Math.pow(10,len-1) ;
int first = (s.charAt(0) - '0') ;
int last = Integer.parseInt(s.substring(1)) ;
if(first==1){
return countDigitOne(power-1) + countDigitOne(last) + last + 1 ;
}else{
return power + first*countDigitOne(power-1)+countDigitOne(last) ;
}
}
}