1. LCR 027. 回文链表 - 力扣(LeetCode)
思路:我们找到链表的中间节点,之后将链表分割,将后一部分的链表逆置,与另一个链表进行比较。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
//找寻中间节点函数
struct ListNode* middlenode(struct ListNode* head)
{
struct ListNode* slow,*fast;
slow=fast=head;
while(fast&&fast->next)
{
slow=slow->next;
fast=fast->next->next;
}
return slow;
}
//链表逆置函数
struct ListNode* reverseList(struct ListNode* head)
{
struct ListNode* cur = head;
struct ListNode* newhead=NULL;
while(cur)
{
struct ListNode* next = cur->next;
cur->next=newhead;
newhead=cur;
cur=next;
}
return newhead;
}
//判断函数
bool isPalindrome(struct ListNode* head)
{
struct ListNode* mid = middlenode(head);
struct ListNode* rHead = reverseList(mid);
struct ListNode* curA=head;
struct ListNode* curR=rHead;
while(curA&&curR)
{
if(curA->val!=curR->val)
{
return false;
}
else
{
curA=curA->next;
curR=curR->next;
}
}
return true;
}
2. 21. 合并两个有序链表 - 力扣(LeetCode)
思路:创建一个新的链表,两个指针对原来两个升序链表的头节点的值进行判断,之后将较小的值放入新的链表中。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* mergeTwoLists(struct ListNode* l1, struct ListNode* l2)
{
if(l1==NULL) return l2;
if(l2==NULL) return l1;
struct ListNode *head=NULL,*tail=NULL;
while(l1&&l2)
{
if(l1->val<l2->val)
{
if(head==NULL)
{
head=tail=l1;
}
else
{
tail->next=l1;
tail=tail->next;
}
l1=l1->next;
}
else
{
if(head==NULL)
{
head=tail=l2;
}
else
{
tail->next=l2;
tail=tail->next;
}
l2=l2->next;
}
}
if(l1)
{
tail->next=l1;
}
if(l2)
{
tail->next=l2;
}
return head;
}
3. 面试题 02.02. 返回倒数第 k 个节点 - 力扣(LeetCode)
思路:让第一个节点率先出动,寻找到合适的位置,能使其再次运动到最后位置的移动次数为,倒数第k个,简单点说就是将问题从找到倒数第k个节点,转化为找到正数第n-k个节点。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
int kthToLast(struct ListNode* head, int k)
{
struct ListNode *prev,*cur;
prev=head;
cur=head;
if(prev->next==NULL) return prev->val;
int i=0;
for(i=0;i<k-1;i++)
{
prev=prev->next;
}
int j=0;
while(prev->next)
{
prev=prev->next;
j++;
}
for(int q=0;q<j;q++)
{
cur=cur->next;
}
return cur->val;
}
4. 876. 链表的中间结点 - 力扣(LeetCode)
思路:快慢指针,让一个指针的速度为另一个指针的两倍,当快指针走到尽头时,慢指针走到链表的中间位置。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* middleNode(struct ListNode* head)
{
struct ListNode* prev,*cur;
if(head==NULL) return head;
prev=head;
cur=head;
while(prev)
{
if(prev->next)
{
if(prev->next->next)
{
prev=prev->next->next;
cur=cur->next;
}
else
{
prev=prev->next;
cur=cur->next;
}
}
else
{
return cur;
}
}
return cur;
}
思路:三个指针,n1,n2,n3。n2与n1迭代向前,交换指针指向方向,n3用来保存n2的下一个节点使迭代继续进行下去。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* reverseList(struct ListNode* head)
{
if(head==NULL)
return head;
struct ListNode* n1,*n2,*n3;
n1=NULL;
n2=head;
n3=head->next;
while(n2)
{
//翻转
n2->next=n1;
//迭代
n1=n2;
n2=n3;
if(n3) n3=n3->next;
}
return n1;
}
思路:双指针,一个指针用来释放对应元素的节点,另一个指针确保链表的连接。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* removeElements(struct ListNode* head, int val)
{
struct ListNode*prev=NULL,*cur=head;
while(cur)
{
if(cur->val==val)
{
if(cur==head)
{
head=cur->next;
free(cur);
cur=head;
}
else
{
prev->next=cur->next;
free(cur);
cur=prev->next;
}
}
else
{
prev=cur;
cur=cur->next;
}
}
return head;
}