C语言实现。
主要考虑两个部分,一是判断单链表是否为回文结构,二是怎么删除倒数第K个节点。
因为单链表的限制,判断回文结构主要有三个思路。
1:直接将所有数字压栈(C语言中可以使用数组来模拟),然后逐次将栈顶元素与单链表进行顺序比较。
2:使用快慢指针找到链表的中点,然后将后半部分数组压栈;
3:使用快慢指针找到链表的中点,然后将后半部分链表逆序;
这里使用第三种方法,其中单链表的逆序使用插头法实现;
对于快慢指针找单链表中点的问题:
while(fast && fast->next){
slow = slow->next;
fast = fast->next->next;
}
如果fast为空代表链表有偶数个节点, fast非空代表有奇数个节点。
对于删除倒数第K个结点,可以先将链表逆序,然后删除整数第K个结点。
我这里采用以空间换时间的方法,开一个指针数组,存下所有位置的指针,然后删除倒数第K个元素时只需考虑第K个元素之前的元素即可。主要考虑K是链表头的特殊情况。
#include <stdio.h>
#include <malloc.h>
//快慢指针找到链表的中间位置,将后半部分逆序,和前半部分依次对比;
typedef struct ListNode //node
{
int val;
struct ListNode* next;
}ListNode;
ListNode* listReverse(ListNode* list)
{
ListNode* p = list->next;
ListNode* q = NULL;
list->next = NULL;
while (p != NULL){
q = p;
p = p->next;
q->next = list;
list = q;
}
return q;
}
int palindromic(ListNode* list)
{
ListNode* fastP = list;
ListNode* slowP = list;
while(fastP && fastP->next){
slowP = slowP->next;
fastP = fastP->next->next;
}
//fastP为空代表链表有偶数个节点, fastP非空代表有奇数个节点;
if (fastP == NULL){
ListNode* newList = listReverse(slowP);
while (newList != NULL){
if (newList->val != list->val){
return 0;
}
newList = newList->next;
list = list->next;
}
return 1;
}
else{
slowP = slowP->next;
ListNode* newList = listReverse(slowP);
while (newList != NULL){
if (newList->val != list->val){
return 0;
}
newList = newList->next;
list = list->next;
}
return 1;
}
}
ListNode* deleteK(ListNode* list, int K)
{
ListNode* allPoints[1000];
ListNode* temp = list;
int index = 0;
allPoints[0] = list;
while(temp != NULL){
index++;
temp = temp->next;
allPoints[index] = temp;
}
if (K == index + 1){
list->next = NULL;
free(list);
return allPoints[1];
}
if (K == 0){
return list;
}
int dindex = index - K;
temp = allPoints[dindex]->next;
allPoints[dindex]->next = allPoints[dindex]->next->next;
free(temp);
return list;
}
main(void)
{
ListNode* list1;
ListNode* temp;
int K;
list1 = (ListNode*)malloc(sizeof(ListNode));
list1->val = 0;
list1->next = NULL;
int val;
printf("Input list1 (ctrl+z to end):\n");
temp = list1;
while (scanf("%d", &val) != EOF){
temp->next = (ListNode*)malloc(sizeof(ListNode));
temp = temp->next;
temp->val = val;
temp->next = NULL;
}
temp = list1;
list1 = list1->next;
free(temp);
printf("Input K:\n");
scanf("%d", &K);
if (palindromic(list1)){
printf("true, ");
}
else{
printf("false, ");
}
ListNode* list2 = deleteK(list1, K);
if (palindromic(list2)){
printf("true");
}
else{
printf("false");
}
}