Leetcode每日一题:234.palindrome-linked-list(回文链表)

在这里插入图片描述
思路:
想法1:快慢指针遍历一遍字符串得到字符串长度以及中间结点的位置,然后对后半部分链表反转,最后从头比较前半部分链表和反转后的后半部分链表;
想法2:利用栈先进后出和函数参数引用来对字符串进行递归比较!
在这里插入图片描述

#include <iostream>
#include <vector>
#include <queue>
using namespace std;

struct ListNode
{
	int val;
	ListNode *next;
	ListNode(int x) : val(x), next(NULL) {}
};

void check(ListNode *head1, int l, ListNode *&head2, int r, bool &flag) //判断链表[l~r]是否为回文  (注意head2是变化的 它要一次次往后走 一定要引用)
{
	if (l >= r)
	{
		return;
	}
	if (r - l >= 2)
	{
		check(head1->next, l + 1, head2, r - 1, flag);
	}

	int a = head1->val, b = head2->val;
	if (a != b)
	{
		flag = false;
	}
	//head2指向下一个结点,此时该函数完成返回其调用函数时,head1也指向前一个结点,这样又能比较两个数是否相等了
	head2 = head2->next;
}

bool isPalindrome(ListNode *head)
{
	//如果有1个及以下的元素,返回true
	if (head == nullptr || head->next == nullptr)
	{
		return true;
	}

	//利用快慢指针求链表个数和中间节点
	int size = 0;
	ListNode *slow = head, *fast = head, *mid_point = nullptr;
	while (fast)
	{ //find mid node
		size++;
		slow = slow->next;
		fast = fast->next ? fast->next->next : fast->next;
	}
	mid_point = slow;
	while (slow)
	{
		size++;
		slow = slow->next;
	}
	bool flag = true;
	check(head, 1, mid_point, size, flag);
	return flag;
}

//之前的思路: 	其一,find mid node 使用快慢指针找到链表中点。 其二,reverse 逆序后半部分。 其三,check 从头、中点,开始比较是否相同。
// bool isPalindrome(ListNode* head) {//O(n)、O(1)
//     ListNode* slow = head, *fast = head,  *prev = nullptr;
//     while (fast){//find mid node
//         slow = slow->next;
//         fast = fast->next ? fast->next->next: fast->next;
//     }
//     while (slow){//reverse
//         ListNode* temp = slow->next;
//         slow->next = prev;
//         prev = slow;
//         slow = temp;
//     }
//     while (head && prev){//check
//         if (head->val != prev->val){
//             return false;
//         }
//         head = head->next;
//         prev = prev->next;
//     }
//     return true;
// }

int main()
{
	ListNode *a1 = new ListNode(1);
	ListNode *a2 = new ListNode(2);
	ListNode *a3 = new ListNode(2);
	ListNode *a4 = new ListNode(1);
	a1->next = a2;
	a2->next = a3;
	a3->next = a4;
	cout << isPalindrome(a1);
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值