1. 移除链表元素
给你一个链表的头节点 head
和一个整数 val
,请你删除链表中所有满足 Node.val == val
的节点,并返回 新的头节点 。
解法1:循环该链表,遇到 Node.val == val
的节点,就删除这个节点,注意删除头节点和非头节点的不同操作。
解法2:不满足 Node.val == val
的节点尾插到newhead的新头之中,返回新头节点
truct ListNode* removeElements(struct ListNode* head, int val){
/* struct ListNode* newhead=head;
while(head&&head->val==val)
{
newhead=head->next;
free(head);
head=newhead;
}
if(newhead==NULL)
{
return newhead;
}
struct ListNode* cur=newhead;
struct ListNode* pre=newhead->next;
while(pre)
{
if(pre->val==val)
{
pre=pre->next;
free(cur->next);
cur->next=pre;
}
else{
cur=pre;
pre=pre->next;
}
}
return newhead;*/
struct ListNode* cur=head;
struct ListNode* newhead=NULL,*tail=NULL;
while(cur)
{
if(cur->val==val)
{
//如果相等,删除该元素
struct ListNode* del=cur;
cur=cur->next;
free(del);
}
else{
if(newhead==NULL)
{
newhead=tail=cur;
}
else
{
tail->next=cur;
tail=tail->next;
}
cur=cur->next;
}
}
if(tail)
tail->next=NULL;
return newhead;
}
2.反转链表
给你单链表的头节点 head
,请你反转链表,并返回反转后的链表。
使用循环方法,需要三个指针,一个记录第三个节点位置,另外两个实现指针的反转。
使用头插法,实现链表反转, 遍历链表,将每个节点头插进新头之中。
struct ListNode* reverseList(struct ListNode* head){
if(head==NULL||head->next==NULL)
{
return head;
}
struct ListNode* cur=head;
struct ListNode* pre=head->next;
struct ListNode*end =head->next->next;
while(pre)
{
end=pre->next;
pre->next=cur;
cur=pre;
pre=end;
}
head->next=NULL;
return cur;
// 以下是解法2
struct ListNode* cur=head;
struct ListNode* newhead=NULL;
while(cur)
{
if(newhead==NULL)
{
newhead=cur;
cur=cur->next;
newhead->next=NULL;
}
else
{
struct ListNode* next=cur->next;
cur->next=newhead;
newhead=cur;
cur=next;
}
}
return newhead;
}
}
3链表的中间结点
给你单链表的头结点 head
,请你找出并返回链表的中间结点。
解法1:计数解法,算出总节点个数,然后算出一半时指针走到哪个节点.
解法2:快慢指针,一个指针走一步,一个指针走两步,快指针走到头,慢指针刚好到一半的位置
struct ListNode* middleNode(struct ListNode* head){
/*if(head==NULL||head->next==NULL)
{
return head;
}
int count=0;
struct ListNode*cur=head;
while(cur)
{
count++;
cur=cur->next;
}
count=count/2;
cur=head;
while(count)
{
cur=cur->next;
count--;
}
return cur;*/
// 快慢指针
struct ListNode *slow=head;
struct ListNode *fast=head;
while(fast&&fast->next)
{
slow=slow->next;
fast=fast->next->next;
}
return slow;
}
4.链表中倒数第k个结点_牛客题霸_牛客网
输入一个链表,输出该链表中倒数第k个结点
解法1:计数解法,算出总节点个数n,然后算出n-k步时指针走到哪个节点.
解法2:快慢指针,快指针先走k步,慢指针开始同时走,快指针走到链表结尾,慢指针所指向的位置就是倒是第k个节点。
struct ListNode* FindKthToTail(struct ListNode* pListHead, int k ) {
// write code here
if(k<=0)
return NULL;
struct ListNode* pre=pListHead;
struct ListNode* cur=pListHead;
while(k--)
{
if(pre)
{
pre=pre->next;
}
else {
return NULL;
}
}
while (pre) {
pre=pre->next;
cur=cur->next;
}
return cur;
}
5. 合并两个有序链表
将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。
解法:用两个指针比较两个链表,取小的尾插到新头之中,同时该指针向后走,当有一个走到头,退出循环,将另一个的尾指针指向这个未走到头的指针。
truct ListNode* mergeTwoLists(struct ListNode* list1, struct ListNode* list2){
if(list1==NULL)
return list2;
if(list2==NULL)
return list1;
struct ListNode* head=NULL;
struct ListNode* tail=NULL;
struct ListNode*p1=list1;
struct ListNode*p2=list2;
while(p1&&p2)
{
if(p1->valval)
{
//头插
if(head==NULL)
{
tail=head=p1;
p1=p1->next;
}
else
{
tail->next=p1;
tail=tail->next;
p1=p1->next;
}
}
else
{
if(head==NULL)
{
tail=head=p2;
p2=p2->next;
}
else
{
tail->next=p2;
tail=tail->next;
p2=p2->next;
}
}
}
if(p1)
{
tail->next=p1;
}
if(p2)
{
tail->next=p2;
}
return head;
}
6.链表的回文结构_牛客题霸_牛客网
对于一个链表,请设计一个时间复杂度为O(n),额外空间复杂度为O(1)的算法,判断其是否为回文结构。
给定一个链表的头指针A,请返回一个bool值,代表其是否为回文结构。保证链表长度小于等于900
解法1:先找到链表中间结点,之后在中间节点之后逆转链表,逆转之后循环链表判断两个链表是否值都相同,如果全部相同,则证明其为回文结构。
/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) : val(x), next(NULL) {}
};*/
struct ListNode* reverseList(struct ListNode* head) {
if (head == nullptr || head->next == nullptr) {
return head;
}
struct ListNode* cur = head;
struct ListNode* pre = head->next;
struct ListNode* end = head->next->next;
while (pre) {
end = pre->next;
pre->next = cur;
cur = pre;
pre = end;
}
head->next = nullptr;
return cur;
}
struct ListNode* middleNode(struct ListNode* head) {
/*if(head==NULL||head->next==NULL)
{
return head;
}
int count=0;
struct ListNode*cur=head;
while(cur)
{
count++;
cur=cur->next;
}
count=count/2;
cur=head;
while(count)
{
cur=cur->next;
count--;
}
return cur;*/
// 快慢指针
struct ListNode* slow = head;
struct ListNode* fast = head;
while (fast && fast->next) {
slow = slow->next;
fast = fast->next->next;
}
return slow;
}
class PalindromeList {
public:
bool chkPalindrome(ListNode* A) {
// write code here
struct ListNode *B=middleNode(A);
struct ListNode* C = reverseList(B);
while (A&&C) {
if (A->val != C->val) {
return false;
}
A = A->next;
C=C->next;
}
return true;
}
};