00125 验证回文串
题目描述
给定一个字符串,验证它是否是回文串,只考虑字母和数字字符,可以忽略字母的大小写。
说明:本题中,我们将空字符串定义为有效的回文串。
示例 1:
输入: "A man, a plan, a canal: Panama"
输出: true
示例 2:
输入: "race a car"
输出: false
力扣地址
解题报告
采用双指针
本题解由微信公众号
小猿刷题
提供, 错误之处, 欢迎指正.
- 分别从头部和尾部进行扫描(只扫描字母和数字), 比较对应位置是否相同字母(考虑到存在大小写,所以统一转换为大/小写进行比较),
- 对应位字母不同则表示不是回文串,直至比较结束,均相等则表示是回文串.
/**
* 微信公众号"小猿刷题"
*/
class Solution {
public boolean isPalindrome(String s) {
int i = 0;
int j = s.length() - 1;
while(i <= j) {
char ci = s.charAt(i);
char cj = s.charAt(j);
if(!Character.isLetterOrDigit(ci)){
i ++;
} else if(!Character.isLetterOrDigit(cj)){
j --;
} else {
// 判断是否相等(不区分大小写)
if(Character.toLowerCase(ci) != Character.toLowerCase(cj)){
return false;
}
j --;
i ++;
}
}
return true;
}
}
上面双指针通过在遍历过程中筛选字母/数字进行比较,也可以先进行串规整(正则替换掉字母数字以外的字符,统一转换大/小写),再头尾进行对比.
/**
* 微信公众号"小猿刷题"
*/
class Solution {
public boolean isPalindrome(String s) {
s = s.replaceAll("[^a-zA-Z0-9]", "").toLowerCase();
for(int i = 0; i < s.length() / 2; i ++){
if(s.charAt(i) != s.charAt(s.length() - 1 -i)){
return false;
}
}
return true;
}
}
小猿刷题
00234 回文链表
题目描述
请判断一个链表是否为回文链表。
示例 1:
输入: 1->2
输出: false
示例 2:
输入: 1->2->2->1
输出: true
进阶:
- 你能否用 O(n) 时间复杂度和 O(1) 空间复杂度解决此题?
力扣地址
- https://leetcode.com/problems/palindrome-linked-list/
- https://leetcode-cn.com/problems/palindrome-linked-list/
解题报告
利用栈
本题解由微信公众号
小猿刷题
提供, 错误之处, 欢迎指正.
利用栈的特性(先进后出)保存链表,然后在元素逐个出栈过程中,从链表依次进行比较.
/**
* 微信公众号"小猿刷题"
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public boolean isPalindrome(ListNode head) {
Stack<Integer> stack = new Stack<>();
ListNode curr = head;
while(curr != null){
stack.add(curr.val);
curr = curr.next;
}
curr = head;
while(!stack.isEmpty()){
int val = stack.pop();
if(val != curr.val){
return false;
}
curr = curr.next;
}
return true;
}
}
利用List
本题解由微信公众号
小猿刷题
提供, 错误之处, 欢迎指正.
既然利用栈可以,同样的利用list也可以解决,链表存储list,再利用list的特性依次遍历首尾对比.
/**
* 微信公众号"小猿刷题"
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public boolean isPalindrome(ListNode head) {
List<Integer> list = new ArrayList<>();
ListNode curr = head;
while(curr != null){
list.add(curr.val);
curr = curr.next;
}
for (int i = 0; i < list.size() / 2; i++){
if((int)list.get(i) != (int)list.get(list.size() - 1 -i)){
return false;
}
}
return true;
}
}
双指针
本题解由微信公众号
小猿刷题
提供, 错误之处, 欢迎指正.
- 快慢指针,快指针移动2次,满指针移动1次,当快指针移动至末尾时,慢指针刚好在链表中间位置.
- 反转慢指针, 同链表头部元素依次进行比较, 遇到不相同的元素则表示非回文联表. 直至结束.
/**
* 微信公众号"小猿刷题"
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public boolean isPalindrome(ListNode head) {
ListNode fast = head;
ListNode slow = head;
while(fast != null && fast.next != null){
slow = slow.next;
fast = fast.next.next;
}
fast = head;
slow = reverse(slow);
while (slow != null) {
if (slow.val != fast.val) {
return false;
}
slow = slow.next;
fast = fast.next;
}
return true;
}
// 链表反转
public ListNode reverse(ListNode head) {
ListNode target = null;
ListNode current = head;
while (current != null) {
ListNode nextTemp = current.next;
current.next = target;
target = current;
current = nextTemp;
}
return target;
}
}
小猿刷题
网友评论