链表-判断回文链表

本文介绍了如何使用双指针技巧判断字符串和链表是否为回文。对于字符串,通过左右指针相向移动进行比较;对于链表,采用快慢指针断链后再翻转后半段链表进行对比。两种方法均能在O(n)的时间复杂度内完成,空间复杂度分别为O(n)和O(1)。
摘要由CSDN通过智能技术生成

判断是否回文字符串- 双指针技巧

var isPalindrome = function (s) {
  let left = 0; right = s.length - 1 // // 一左一右两个指针相向而行
  while (left < right) {
    if (s.charAt(left) != s.charAt(right)) {
      return false
    }
    left++
    right--
  }
  return true
};

leetcode:234. 回文链表

解题思路:

  1. 方法一:遍历一遍,把值放入数组中,然后用双指针判断是否回文。时间复杂度O(n)O(n) ,空间复杂度O(n)O(n)
  2. 方法二:

    快慢指针,起初都指向表头,快指针一次走两步,慢指针一次走一步

  • 遍历结束时:要么,slow 正好指向中间两个结点的后一个。要么,slow 正好指向中间结点。

  • 用 prev 保存 slow 的前一个结点,通过prev.next = null断成两个链表。

  • 将后半段链表翻转,和前半段从头比对。空间复杂度降为O(1)

//方法一
var isPalindrome = function (head) {
  const vals = []
  while (head) {
    vals.push(head.val)
    head = head.next
  }
  let left = 0;
  right = vals.length - 1 //  一左一右两个指针相向而行
  while (left < right) {
    if (vals[left] != vals[right]) {
      return false
    }
    left++
    right--
  }
  return true
};
方法二:

var isPalindrome = function (head) {
  if (!head || !head.next) {
    return true
  }
  let fast = head,
    slow = head
  let prev
  while (fast && fast.next) {
    prev = slow
    slow = slow.next
    fast = fast.next.next
  }
  prev.next = null //断成两个链表

  //翻转后半段
  let head2 = null
  while (slow) {
    const tmp = slow.next
    slow.next = head2
    head2 = slow
    slow = tmp
  }

  //比对
  while (head && head2) {
    if (head.val != head2.val) {
      return false
    }
    head = head.next
    head2 = head2.next
  }
  return true
};

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
题目描述: 给定一个链表,判断该链表是否是回文结构。 例如:1->2->3->2->1 是回文链表。 1->2->3->3->2->1 是回文链表。 输入: 待判断的整数链表。 输出: 若是回文结构则输出1,否则输出0。 代码实现: ```c #include <stdio.h> #include <stdlib.h> //定义链表节点 typedef struct ListNode{ int val; struct ListNode *next; }ListNode; //创建链表 ListNode* createList(int n){ ListNode *head = (ListNode*)malloc(sizeof(ListNode)); ListNode *p = head; for(int i=1; i<=n; i++){ ListNode *newNode = (ListNode*)malloc(sizeof(ListNode)); newNode->val = i; p->next = newNode; p = p->next; } return head->next; } //反转链表 ListNode* reverseList(ListNode *head){ ListNode *prev = NULL; ListNode *cur = head; while(cur != NULL){ ListNode *next = cur->next; cur->next = prev; prev = cur; cur = next; } return prev; } //判断回文链表 int isPalindrome(ListNode* head){ if(head == NULL || head->next == NULL){ return 1; } ListNode *slow = head; ListNode *fast = head; while(fast->next != NULL && fast->next->next != NULL){ slow = slow->next; fast = fast->next->next; } ListNode *mid = slow; ListNode *secondHead = reverseList(mid->next); ListNode *p1 = head; ListNode *p2 = secondHead; int res = 1; while(p2 != NULL){ if(p1->val != p2->val){ res = 0; break; } p1 = p1->next; p2 = p2->next; } mid->next = reverseList(secondHead); return res; } int main(){ //创建链表 ListNode *head = createList(5); //打印链表 ListNode *p = head; while(p != NULL){ printf("%d ",p->val); p = p->next; } printf("\n"); //判断回文链表 int res = isPalindrome(head); printf("%d\n",res); return 0; } ``` 注释详细,逻辑清晰。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值