判断回文链表
问题描述
请判断一个链表是否为回文链表
示例
输入: 1->2
输出: false
示例
输入: 1->2->2->1
输出: true
分析
利用栈来做,偶数情况下前半段入栈,后半段与弹栈元素做对比即可,下面代码可以正确运行,但我感觉设计得复杂了,有时间再来优化一下
代码
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public static boolean isPalindrome(ListNode head) {
if (head == null) return true;
Stack stack = new Stack(); //定义栈结构
int len = computeLen(head); //head = compute(head)? ;
int count = 0; //辅助计数器
/*遍历链表,进栈进一半*/
while (head.next != null) {
++count;
if (count > len / 2) break; //进一半
stack.push(head);
head = head.next;
}
/*判断是否回文*/
/*链表长度为偶数*/
if (len % 2 == 0) {
for (int k = 0; k < len / 2; k++) {
ListNode listNode = (ListNode) stack.pop();
int i = listNode.val;
if (i != head.val) {
return false;
} else {
head = head.next;
}
}
return true;
}else {
for (int k = 0; k < len / 2; k++) {
ListNode listNode = (ListNode) stack.pop();
int i = listNode.val;
if (i != head.next.val) {
return false;
} else {
head = head.next;
}
}
return true;
}
}
public static int computeLen(ListNode head){
/*求链表长度*/
int len = 1 ;
while (head.next!=null){
++len ;
head = head.next ;
}
return len ;
}}
==========update by 2020 4/16 ==================
C++完整可运行源代码(经过VS2015、devC++编译运行通过)
#include "stdio.h"
#include "string.h"
#include "ctype.h"
#include "stdlib.h"
#include "io.h"
#include "math.h"
#include "time.h"
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
#define MAXSIZE 20 /* 存储空间初始分配量 */
typedef int Status;/* Status是函数的类型,其值是函数结果状态代码,如OK等 */
typedef int ElemType;/* ElemType类型根据实际情况而定,这里假设为int */
/* 顺序栈结构 */
typedef struct
{
ElemType data[MAXSIZE];
int top; /* 用于栈顶指针 */
}SqStack;
/* 构造一个空栈S */
Status InitStack(SqStack *S)
{
/* S.data=(SElemType *)malloc(MAXSIZE*sizeof(SElemType)); */
S->top = -1;
return OK;
}
/* 插入元素e为新的栈顶元素 */
Status Push(SqStack *S, ElemType e)
{
if (S->top == MAXSIZE - 1) /* 栈满 */
{
return ERROR;
}
S->top++; /* 栈顶指针增加一 */
S->data[S->top] = e; /* 将新插入元素赋值给栈顶空间 */
return OK;
}
/* 若栈不空,则删除S的栈顶元素,用e返回其值,并返回OK;否则返回ERROR */
Status Pop(SqStack *S, ElemType *e)
{
if (S->top == -1)
return ERROR;
*e = S->data[S->top]; /* 将要删除的栈顶元素赋值给e */
S->top--; /* 栈顶指针减一 */
return OK;
}
/* 若栈不空,则用e返回S的栈顶元素,并返回OK;否则返回ERROR */
ElemType GetTop(SqStack S, ElemType *e)
{
if (S.top == -1)
return ERROR;
else
*e = S.data[S.top];
return *e;
}
typedef struct ListNode
{
ElemType val;
struct ListNode *next;
}ListNode;
typedef struct ListNode *LinkList; /* 定义LinkList */
/* 初始化顺序线性表 */
Status InitList(LinkList *L)
{
*L = (LinkList)malloc(sizeof(ListNode)); /* 产生头结点,并使L指向此头结点 */
if (!(*L)) /* 存储分配失败 */
return ERROR;
//(*L)->val = NULL;
(*L)->next = NULL; /* 指针域为空 */
return OK;
}
/* 初始条件:顺序线性表L已存在,1≤i≤ListLength(L), */
/* 操作结果:在L中第i个位置之前插入新的数据元素e,L的长度加1 */
Status ListInsert(LinkList *L, int i, ElemType e)
{
int j;
LinkList p, s;
p = *L;
j = 1;
while (p && j < i) /* 寻找第i个结点 */
{
p = p->next;
++j;
}
if (!p || j > i)
return ERROR; /* 第i个元素不存在 */
s = (LinkList)malloc(sizeof(ListNode)); /* 生成新结点(C语言标准函数) */
s->val = e;
s->next = p->next; /* 将p的后继结点赋值给s的后继 */
p->next = s; /* 将s赋值给p的后继 */
return OK;
}
int ListLength(LinkList L)
{
int i = 0;
LinkList p = L->next; /* p指向第一个结点 */
while (p)
{
i++;
p = p->next;
}
return i;
}
Status Palindrome(LinkList *L , int pos ) {
ElemType e,e1;
LinkList p;
SqStack s;
/*初始化栈*/
InitStack(&s);
p = *L;
/*判断是否空链表*/
if (!p) {
return FALSE;
}
/*前半元素进栈*/
for (int i = 0; i < pos; i++) {
p = p->next;
Push(&s, p->val);
}
/*出栈元素与后半元素比较*/
for (int j = 0; j < pos; j++) {
p = p->next;
e1 = GetTop(s, &e); /*取栈顶元素*/
Pop(&s, &e); /*删除栈顶元素*/
if (p->val != e1) {
return FALSE;
}
}
return TRUE;
}
int main()
{
ElemType e;
LinkList L;
Status i;
/*初始化单链表*/
i = InitList(&L);
/*依次采用尾插法插入元素*/
ListInsert(&L, 1, 1);
ListInsert(&L, 2, 2);
ListInsert(&L, 3, 3);
ListInsert(&L, 4, 3);
ListInsert(&L, 5, 2);
ListInsert(&L, 6, 2);
/*求长度求中间位置*/
int j = ListLength(L);
if (j % 2 == 0) { /*回文链表一定是偶数*/
int pos = j / 2;
int k = Palindrome(&L, pos);
if (k == TRUE) {
printf("true");
}
else {
printf("false");
}
}
system("pause");
return 0;
}