力扣题解: 00125 & 00234

173 阅读3分钟
原文链接: mp.weixin.qq.com

00125 验证回文串

题目描述

给定一个字符串,验证它是否是回文串,只考虑字母和数字字符,可以忽略字母的大小写。

说明:本题中,我们将空字符串定义为有效的回文串。

示例 1:

    输入: "A man, a plan, a canal: Panama"

    输出: true

示例 2:

    输入: "race a car"

    输出: false

力扣地址

  • https://leetcode.com/problems/valid-palindrome/

  • https://leetcode-cn.com/problems/valid-palindrome/

解题报告

采用双指针

本题解由微信公众号 小猿刷题提供, 错误之处, 欢迎指正.

  • 分别从头部和尾部进行扫描(只扫描字母和数字), 比较对应位置是否相同字母(考虑到存在大小写,所以统一转换为大/小写进行比较),

  • 对应位字母不同则表示不是回文串,直至比较结束,均相等则表示是回文串.

    /**

    * 微信公众号"小猿刷题"

    */

    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;

    }

    }