leetcode[Largest Palindrome Product]

错误解法(这种解法对于位数高于4的输入会超时):java

public class Solution {
	private int low(int digit){//计算位数为digit的数的最小值
		int res = 1;
		for(int i = 0; i < digit - 1; i++){
			res *= 10;
		}
		return res;
	}
	
	private int high(int digit){//计算位数为digit的数的最大值
		int res = 1;
		for(int i = 0; i < digit; i++){
			res *= 10;
		}
		return res - 1;
	}
	
	private boolean isPalindrome(int x){//判断一个数是不是回文数
		int fromTail = 0;
		int fromHead = x;
		if(x < 0){//负数不是回文数
			return false;
		}
		if(x % 10 == 0 && x != 0){//这种状况不能用下面的方式判断,由于fromTail的最高位始终是0
			return false;
		}
		while(fromHead > fromTail){
			fromTail = fromTail * 10 + (fromHead % 10);
			fromHead /= 10;
			//System.out.println("head:" + fromHead + "   tail:" + fromTail);
		}
		
		if(fromTail == fromHead){
			return true;
		} else if(fromTail / 10 == fromHead){
			return true;
		} else{
			return false;
		}
	}
	
    public int largestPalindrome(int n) {//计算的是最大两个数相乘造成的回文数,只不过将结果对1337取余,不是求回文数对1337取余后的最大的数
        int low = low(n);//有更简单的方式:int low = (int) Math.pow(10, n - 1)
        int high = high(n);//有更简单的方式:int high = (int) Math.pow(10, n) - 1
        int product = 0;
        int res = 0;
        for(int a = low; a <= high; a++){
        	for(int b = low; b <= high; b++){
            	product = a * b;
            	if(isPalindrome(product)){
            		//System.out.println(product);
            		res = Math.max(res, product);
            	}
        	}
        }        
        return res % 1337;
    }
}

解法一:

public class Solution {
	private long createPalindrome(int left){//以左半部为
		String str = left + new StringBuilder().append(left).reverse().toString();
        return Long.parseLong(str);
	}
	
	//前面会超时是由于时间复杂度是O(N*N),这里采用取数的半边,来判断两个n位数的乘积是不是回文数
    public int largestPalindrome(int n) {//计算的是最大两个数相乘造成的回文数,只不过将结果对1337取余,不是求回文数对1337取余后的最大的数
    	int high = (int) (Math.pow(10, n) - 1);
    	int low = (int) Math.pow(10, n-1);
    	// e.g. if n = 3 then maxNumber = 999 x 999 = 998001 so firstHalf = 998
    	
    	//long的乘法要将high转换一下,要否则仍是至关于两个int在相乘!!!
    	long max = (long)high * high;//求出最大的数,既然这个数是最大的,那么高位的左半部也是最大的,从左半部开始往下构造回文数
    	
    	//有一个细节,除n=1外,n位数和n位数相乘的回文数的位数为偶数
    	
    	//因此n=1时,单独处理
    	if(n == 1){
    		return 9;
    	}
    	
    	int firstHalf = (int)(max / Math.pow(10, n));
    	
    	for(int i = firstHalf; i >= low; i--){
    		//System.out.println("左半部 : " + i);
    		long createPalin = createPalindrome(i);
    		//System.out.println("createPalin : " + createPalin);
    		//判断这个经过左半部构造出的回文数是不是由low到high这个范围内的两个数的乘积构成的
    		for(int j = high; j >= low; j--){
    			//System.out.println("j : " + j);
    			
    			if(createPalin / j > high){//限制另外一个因子
    				break;
    			}
    			
    			if(createPalin % j == 0){//这里只保证了其中一个因子是在low到high这个范围内,因此在前面还要限制另外一个因子
    				//System.out.println("createPalin : " + createPalin);
    				return (int) (createPalin % 1337);
    			}
    		}
    	}
    	
    	return -1;
    }
}