Java判断一个字符串或者一个数字是否为回文串或者回文数的一些思考

利用字符串转换和数学法

在这里插入图片描述在leetcode上刷到这样一道题目,很明显:
(1)该数字 < 0,输出的是false,
(2)比如10、120等%10 = 0的,也返回false,但是此时要注意:0%10也是等于0的,而0也是回文数!
(3)问题的关键在:如何判断左边和右边是对称的呢?
A、将数字转换成字符串
B、数学法:利用求余、整除。

1. 将数字转换成字符串

方法一:
基本思想:将该数字转换为字符串,直接调用java中的字符串的反转函数

比如数字12345,调用函数得54321
![在这里插入图片描述](https://img-blog.csdnimg.cn/20200414171414546.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L01PX1JPTQ==,size_16,color_FFFFFF,t_70

方法二:
基本思想:将该数字转换为字符串,再利用字符串的charAt()方法从字符串的两端逐一判断,若不同则直接返回错误。

比如12345,用first、last指针标记,每轮判charAt(first)是否与charAt(last)相同,1和5不同直接返回false。
在这里插入图片描述
方法三:
基本思想:将该数字转换为字符串,然后切分放入数组,两端逐一比较。该方法跟方法二类似,就比方法二多了切片放入数组这一步。
在这里插入图片描述

2、数学法:利用求余、整除

方法一:将整个数翻转,与之前得数比较

比如12345,翻转后为54321,而12345 != 54321
在这里插入图片描述

方法二:翻转一半的数,然后用其中一半与另一半比较,这个比较像链表判断回文串的做法(链表法,下面再说)

比如判断数字12321。将后两位翻转后为12,与前两位相等。数字123456,将后三位翻转后为654,与前三位不等

在这里插入图片描述变量halfReverse来存放翻转数字的后n/2位,while(x > halfReverse)这个条件很妙, 在翻转过程中x < halfReverse 说明已经翻转了一半的数位。
最后当数字长度为偶数时,直接比较x == halfReverse;当数字长度为奇数时,我们可以通过revertedNumber/10去除处于中位的数字。

利用栈、链表

这里形参都是字符串,若是数字的话,需要再写一个数字转换成字符串的函数。

1、栈

基本思想:利用栈的先进后出思想,将字符串的一半入栈,然后每次都利用字符串的后半部分与栈顶比较,若相同则弹出栈顶元素,继续比较下一个元素。

比如abcba,入栈ab,因为字符串是奇数个,说明最中间的哪个不用比较,指针需要格外的后移一位,比较字符串ba,此时栈顶元素为b,字符串指针指向b,两者相同,栈顶元素弹出,字符串指针后移。栈顶元素变为a,字符串指针指向的也是a,栈顶元素弹出。循环结束,说明是回文串。

//节点类
class Node1<T>{
	T data;
	Node1<T> next;
	Node1(){
		this(null);
	}
	Node1(T data){
		this.data = data;
		this.next = null;
	}
}

//链栈类
class LinkStack1<T>{
	private Node1<T> top;
	public boolean isEmpty() {
		return top == null;
	}
	public void push(T data) {
		Node1<T> p = new Node1<T>(data);
		p.next = top;
		top = p;
	}
	public T pop() {
		if (isEmpty())
			return null;
		else {
			Node1<T> p = top;
			top = top.next;
			return p.data;
		}
	}
	public T peek() {
		if(!isEmpty())
			return top.data;
		else
			return null;
	}
}

public class isPalindrome {
	//判断是否为回文串的函数
	public void stack(String str) {    //判断是否为回文串
		String newstr = str.toUpperCase();    //将字符串的单词转换为小写字母
		String[] strs = newstr.split("");     //将字符串拆分成放入数组
		int length = strs.length / 2;
		LinkStack1<String> L= new LinkStack1<String>(); 
		for(int i = 0; i < length; i++) {  //一半入栈
			L.push(strs[i]);   //进栈        
		}
		if (strs.length % 2 != 0)
			length++;
		for(int i = length; i < strs.length; i++) {
			if (L.peek().equals(strs[i])) {
				L.pop();
			}
			else {
				return;
			}
		}
		System.out.println(str + " 是回文串!");
	}
}
2、 链表

基本思想:利用双向循环链表的双向和循环性,用head.next从当头指针,实现从头开始,用head.period从当尾指针,实现从尾部开始。这个时候何时结束循环很关键。

class LinkList{    //用链表判断是否为回文串
	Node head = new Node();   //头指针
	class Node{      //节点类(双向循环)
		String data;
		Node next = null;
		Node prior = null;
		Node(){
			this(null);
		}
		Node(String data){
			this.data = data;
		}
	}
	Node temp = head;  //记录尾结点
	public void append(String data) {   //尾插法
		Node cur = new Node(data);
		temp.next = cur;
		cur.prior = temp;
		temp = temp.next;
	}
	public void cir() {     //形成循环链表
		temp.next = head;
		head.prior = temp;
	}
	public void HTpoiter(String str){     //头尾指针判断
		String newstr = str.toUpperCase();    //将字符串的单词转换为小写字母
		String[] strs = newstr.split("");     //将字符串拆分成放入数组
		for(int i = 0; i < strs.length; i++) {
			append(strs[i]);        //形成双向链表
		}
		cir();    //形成双向循环链表
		Node t1 = head.next;
		Node t2 = head.prior;
		int cnt = 0;    //结点个数统计
		while(cnt != strs.length / 2) {      //等于一半终止
			if (t1.data.equals(t2.data)) {
				t1 = t1.next;
				t2 = t2.prior;  //字符相同则比较下一个
				cnt++;
			}
			else {
				System.out.println(str + " 不是回文串!");   //不同直接输出
				return;
			}
		}
		System.out.println(str + " 是回文串!");	
	}
}
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值