Palindrome总结

这篇文章总结leetcode中回文的题目,其中关于palindrome partition有两道题目,第二道属于动态规划的题目,我们动态规划的总结中讨论。简单的讲回文就是将它翻转后和原来一样。

[b]1,Palindrome Number[/b]
给定一个数字,判断它是否为回文数。

对于数字来讲,负数不属于回文数,对于正数,我们将它逆转,然后与原始值比较,如果相等就为回文数。代码如下:

public class Solution {
public boolean isPalindrome(int x) {
if(x < 0) return false;
int result = 0;
int tem = x;
while(x != 0) {
result = result * 10 + x % 10;
x /= 10;
}
if(result == tem)
return true;
return false;
}
}


[b]2,Valid Palindrome[/b]
给定一个字符串判断是否为回文,只考虑数字和字母,并且不考虑字母大小写问题。
例如:"A man, a plan, a canal: Panama" 是回文字符串
"race a car" 不是回文字符串

既然只考虑数字和字母,我们就要想办法把其它的字符去除,这里我们用到正则表达式来处理,我们替换掉除字母和数字以外其它的字符,正则表达式为[^0-9a-z-A-Z],代码如下:

public class Solution {
public boolean isPalindrome(String s) {
s = s.replaceAll("[^a-zA-Z0-9]","").toLowerCase();
int l = 0;
int r = s.length() - 1;
while(l < r) {
if(s.charAt(l) != s.charAt(r)) {
return false;
} else {
l ++;
r --;
}
}
return true;
}
}


[b]3,Palindrome Linked List[/b]
给定一个链表,判断是否为回文链表。

解决这道题我们要用快慢指针,找到中间点,接下来我们可以用栈操作,把前半段压入到堆栈中,然后和后半段比较;也可以将后半段反转与前半段进行比较。注意的问题是用堆栈的时候要考虑链表元素个数为奇数还是偶数。

堆栈解法:

/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
public class Solution {
public boolean isPalindrome(ListNode head) {
Stack<Integer> stack = new Stack<Integer>();
if(head == null) return true;
ListNode fast = head;
ListNode slow = head;
while(fast.next != null && fast.next.next != null) {
stack.push(slow.val);
slow = slow.next;
fast = fast.next.next;
}
head = slow.next;

// 对奇偶数的判断
if(fast.next != null)
stack.push(slow.val);

//比较前后半段
while(!stack.isEmpty()) {
if(stack.pop() != head.val){
return false;
} else {
head = head.next;
}
}
return true;
}
}


反转解法:

/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
public class Solution {
public boolean isPalindrome(ListNode head) {
if(head == null) return true;
ListNode fast = head;
ListNode slow = head;
//得到中间节点
while(fast.next != null && fast.next.next != null) {
slow = slow.next;
fast = fast.next.next;
}
fast = head;
head = slow.next;

//反转后半段
ListNode pre = null;
ListNode tem = null;
while(head != null) {
tem = head.next;
head.next = pre;
pre = head;
head = tem;
}

//比较前半段与后半段
while(pre != null) {
if(fast.val != pre.val) {
return false;
} else {
fast = fast.next;
pre = pre.next;
}
}
return true;
}
}


[b]4,Palindrome Partitioning[/b]
给定一个字符串s,把s分为很多子串,每个子串都为回文字符串,列出所有可能的结果。
例如:给定s = "aab"
输出: [ ["aa","b"], ["a","a","b"] ]

因为要列出所有的结果,很容易想到用回溯法。代码如下:

public class Solution {
public List<List<String>> partition(String s) {
List<List<String>> llist = new ArrayList<List<String>>();
LinkedList<String> list = new LinkedList<String>();
if(s == null) return llist;
partitionPalindro(0, s, llist, list);
return llist;
}
public void partitionPalindro(int start, String s, List<List<String>> llist, LinkedList<String> list) {
if(start == s.length()) {
llist.add(new LinkedList<String>(list));
return;
}
for(int i = start; i < s.length(); i++) {
if(isPalindrom(s.substring(start, i + 1))) {
list.add(s.substring(start, i + 1));
partitionPalindro(i + 1, s, llist, list);
list.removeLast();
}
}
}

private boolean isPalindrom(String s) {
int l = 0;
int r = s.length() - 1;
while(l < r) {
if(s.charAt(l) != s.charAt(r)) {
return false;
} else {
l ++;
r --;
}
}
return true;
}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值