4.26 中心拓展法

中心拓展法

解决问题:回文字符

原理:循环各字符,拿到一个字符s.charAT(i),分别先向左或者右边扩展,寻找与中心点(也就是该字符)相等的字符,寻找结束。之后同时拓展左右两边,寻找左右两点相等的字符,直至不相等,则以中心字符的寻找结束,进入下一次以s.charAT(i+1)为中心来拓展寻找回文字符。

public String longestPalindrome(String s) {
        if(s==null || s.length()==0)return "";
		int length=s.length();
		int i=0, j=0, left=0, right=0, len=1;//len存回文字符的长度,初始值为1
		int max=0; //记录最长的回文长度
		int start=0; // 记录回文起始位置
		for( ; i<length; i++) {
			left=i-1; //先left right指针分别移动一个位置
			right=i+1;
			while(left>=0 && s.charAt(i)==s.charAt(left)) {
				left--;len++; //若像左边扩散成功,继续扩散并且len长度增加
			}
			while(right<length && s.charAt(i)==s.charAt(right)) {
				right++;len++;	//继续向右边扩散
			}
			while(left>=0 && right<length && s.charAt(left)==s.charAt(right)) {
				left--;right++;
				len+=2; //向两边同时扩散寻找回文字符
			}
			if(len>max) {
				max=len;
				start=left;
			}
			len=1; //每次结束一次中心字符的选取就要对len重新赋值

		}
		return s.substring(start+1, start+max+1); //substring截取子串,取头不取尾,所以结束的索引要加1
												//start加1,因为while循环退出时,left多减了1
		
    }

Z字形变换

原理:如图所示

class Solution { //while循环太多了,超出时间限制,自己写的测试用例都没问题
    public String convert(String s, int numRows) {
        if(numRows==1)return s;
        char[][] a=new char[1000][1000];
		int length=s.length();
		int row=0, col=0, i=0;
		int end=0;
		while(i<length) {
			if(row==0) {
				while(row<numRows && i<length) {
					a[row][col]=s.charAt(i);
					i++;row++;
				}
			}
			if(row==numRows) {
				row=numRows-1;
				while(row>1 && i<length) {
					a[row-1][col+1]=s.charAt(i);
					row--;col++;
					i++;
				}
				row--;col++;
			}	
			if(i==length)end=col;
		}
		StringBuilder q = new StringBuilder(); //因为新创建用来存储变换后的字符,会发生很多次修改,所以使用StringBuilder对q对象尾部添加字符
		for(int i1=0; i1<numRows; i1++)
			for(int j=0; j<=end; j++) {
				if(a[i1][j] >= 'A' && a[i1][j] <='Z') q.append(a[i1][j]);
			}
		return q.toString();//返回string类对象
    }
}

翻转数字

原理:转换为字符串然后翻转,用try catch处理溢出

String xString=Integer.toString(x);
		String string=xString;
		int flag=1;
		if(x<0) {
			flag=-1;
			string=xString.substring(1);//若为负数去掉符号
		}
		try {
			return Integer.valueOf(new StringBuilder(string).reverse().toString())*flag;
			//reverse返回的是stringbuilder对象,要用tostring返回字符串
		} catch (Exception e) {
			return 0;
		}

下面的是我的题解,虽然ac了,但是时间复杂度不低,而且溢出的判断有些玄学,并不满足所有溢出判断,应该是只能ac这道题。

class Solution {
    public int reverse(int x) {
        int len=0;
		int y=x;
		int ans=0;
		while(Math.abs(y)>0) {
			len++;
			y=y/10;
		}
		y=x;
		int[] num=new int[len];
		int[] renum=new int[len];
		for(int i=0; i<len; i++) {
			num[i]=y%10;
			y=y/10;
		}
		for(int i=0, j=len-1; i<len && j>=0; i++, j--) {
			ans+=Math.pow(10, j)*num[i];
		}
		if(ans==Integer.MIN_VALUE || ans==Integer.MAX_VALUE)return 0;
		else return ans;
		
    }
}

存数组然后再按位存放,有些笨的方法,可以不使用数组。如下:

    public int reverse(int x) {
        long n = 0;
        while(x != 0) {
            n = n*10 + x%10;
            x = x/10;
        } //不需要数组
        return (int)n==n? (int)n:0;
    }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值