[数据结构]链表OJ(leetcode)

目录

数据结构之链表OJ::

                                     1.移除链表元素

                                     2.反转链表

                                     3.链表的中间结点

                                     4.链表中倒数第k个结点

                                     5.合并两个有序链表

                                     6.链表分割

                                     7.链表的回文结构

                                     8.相交链表

                                     9.环形链表

                                    10.环形链表II

                                    11.复制带随机指针的链表


数据结构之链表OJ::

1.移除链表元素

//删除链表中等于给定值val的所有结点
struct ListNode
{
	int val;
	struct ListNode* next;
};
//方法一
struct ListNode* removeElements(struct ListNode* head, int val)
{
	struct ListNode* cur = head, * prev = NULL;
	while (cur != NULL)
	{
		//1.头删
		//2.非头删
		if (cur->val == val)
		{
			if (cur == head)
			{
				head = head->next;
				free(cur);
				cur = head;
			}
			else
			{
				prev->next = cur->next;
				free(cur);
				cur = prev->next;
			}
		}
		else
		{
			prev = cur;
			cur = cur->next;
		}
	}
	return head;
}
//不用二级指针的方法:返回头指针
//main函数调用方式:plist = removeElements(plist,6);
//方法二
struct ListNode* removeElements(struct ListNode* head, int val)
{
	struct ListNode* cur = head;
	struct ListNode* newhead = NULL;
	struct ListNode* tail = NULL;
	while (cur != NULL)
	{
		if (cur->val != val)
		{
			if (newhead == NULL)
			{
				newhead = cur;
				tail = newhead;
				cur = cur->next;
			}
			else
			{
				tail->next = cur;
				cur = cur->next;
				tail = tail->next;
			}
		}
		else
		{
			struct ListNode* del = cur;
			cur = cur->next;
			free(del);
		}
	}
	if (tail != NULL)
	{
		tail->next = NULL;
	}
	return newhead;
}
//方法三:
struct ListNode* removeElements(struct ListNode* head, int val)
{
	struct ListNode* cur = head;
	struct ListNode* guard = (struct ListNode*)malloc(sizeof(struct ListNode));
	struct ListNode* tail = guard;
	while (cur != NULL)
	{
		if (cur->val != val)
		{
			tail->next = cur;
			tail = tail->next;
			cur = cur->next;
		}
		else
		{
			struct ListNode* del = cur;
			cur = cur->next;
			free(del);
		}
	}
	//最后结点是val 就会出现此问题
	if (tail != NULL)
	{
		tail->next = NULL;
	}
	head = guard->next;
	free(guard);
	return head;
}
//替代我们之前实现的二级指针
//1.返回新的链表头 2.设计为带哨兵位

2.反转链表

 

//反转链表
//方法一:取结点头插到新链表
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;
}
//方法二:翻转链表方向
struct ListNode* reverseList(struct ListNode* head)
{
	struct ListNode* prev = NULL;
	struct ListNode* cur = head;
	struct ListNode* next = NULL;
	while (cur)
	{
		next = cur->next;
		cur->next = prev;
		prev = cur;
		cur = next;
	}
	return prev;
}

3.链表的中间结点

//方法一:
struct ListNode* middleNode(struct ListNode* head)
{
	struct ListNode* slow = head;
	struct ListNode* fast = head;
	while (fast && fast->next)
	{
		slow = slow->next;
		fast = fast->next->next;
	}
	return slow;
}
//方法二:
struct ListNode* middleNode(struct ListNode* head)
{
    struct ListNode* cur1 = head;
    int num = 0;
    int mid = 0;
    while (cur1 != NULL)
    {
        num++;
        cur1 = cur1->next;
    }
    mid = num / 2 + 1;
    cur1 = head;
    for (int i = 1; i < mid; i++)
    {
        cur1 = cur1->next;
    }
    return cur1;
}

4.链表中倒数第k个结点

 

//方法一:
struct ListNode* FindKthToTail(struct ListNode* pListHead, unsigned int k) 
{
	
	struct ListNode* cur = pListHead;
    int n = 0;
    while (cur)
    {
        n++;
        cur = cur->next;
    }
    if (k > n)
    {
        return NULL;
    }
    cur = pListHead;
    int pos = n - k + 1;
    for (int i = 1; i < pos; i++)
    {
        cur = cur->next;
    }
    return cur;
}
//方法二:
struct ListNode* FindKthToTail(struct ListNode* pListHead, unsigned int k)
{
	struct ListNode* fast, * slow;
	fast = slow = pListHead;
	while (k--) //走k步
	{
		//k大于链表长度
		if (fast == NULL)
			return NULL;
		fast = fast->next;
	}
	while (fast)
	{
		slow = slow->next;
		fast = fast->next;
	}
	return slow;
}
//方法三:
struct ListNode* FindKthToTail(struct ListNode* pListHead, unsigned int k)
{
    struct ListNode* fast = pListHead;
    struct ListNode* slow = pListHead;
    while (--k)
    {
        if (fast == NULL)
        {
            return NULL;
        }
        fast = fast->next;
    }
    if (fast == NULL)
    {
        return NULL;
    }
    while (fast->next)
    {
        fast = fast->next;
        slow = slow->next;
    }
    return slow;
}

5.合并两个有序链表 

//合并两个有序链表
//不带哨兵位
struct ListNode* mergeTwoLists(struct ListNode* list1, struct ListNode* list2)
{
	if (list1 == NULL)
	{
		return list2;
	}
	if (list2 == NULL)
	{
		return list1;
	}
	struct ListNode* begin1 = list1;
	struct ListNode* begin2 = list2;
	struct ListNode* newlist = NULL;
	struct ListNode* begin3 = newlist;
	while (begin1 != NULL && begin2 != NULL)
	{
		if (newlist == NULL)
		{
			if (begin1->val < begin2->val)
			{
				newlist = begin1;
				begin1 = begin1->next;
				begin3 = newlist;
			}
			else
			{
				newlist = begin2;
				begin2 = begin2->next;
				begin3 = newlist;
			}
		}
		else
		{
			if (begin1->val < begin2->val)
			{
				begin3->next = begin1;
				begin1 = begin1->next;
				begin3 = begin3->next;
			}
			else
			{
				begin3->next = begin2;
				begin2 = begin2->next;
				begin3 = begin3->next;
			}
		}
	}
	if (begin1 == NULL)
	{
		begin3->next = begin2;
	}
	if (begin2 == NULL)
	{
		begin3->next = begin1;
	}
	return newlist;
}
//带哨兵位
struct ListNode* mergeTwoLists(struct ListNode* list1, struct ListNode* list2)
{
	struct ListNode* guard = (struct ListNode*)malloc(sizeof(struct ListNode));
	guard->next = NULL;
	struct ListNode* tail = guard;
	struct ListNode* begin1 = list1;
	struct ListNode* begin2 = list2;
	while (begin1 && begin2)
	{
		if (begin1->val < begin2->val)
		{
			tail->next = begin1;
			begin1 = begin1->next;
			tail = tail->next;
		}
		else
		{
			tail->next = begin2;
			begin2 = begin2->next;
			tail = tail->next;
		}
	}
	if (begin1)
	{
		tail->next = begin1;
	}
	if (begin2)
	{
		tail->next = begin2;
	}
	struct ListNode* head = guard->next;
	free(guard);
	return head;
}

6.链表分割 

//链表分割
struct ListNode* partition(struct ListNode* pHead, int x)
{
	struct ListNode* lessGuard = (struct ListNode*)malloc(sizeof(struct ListNode));
	struct ListNode* lessTail = lessGuard;
	struct ListNode* greaterGuard = (struct ListNode*)malloc(sizeof(struct ListNode));
	struct ListNode* greaterTail = greaterTail;
	lessGuard->next = NULL;
	greaterGuard->next = NULL;
	struct ListNode* cur = pHead;
	while (cur)
	{
		if (cur->val < x)
		{
			lessTail->next = cur;
			cur = cur->next;
			lessTail = lessTail->next;
		}
		else
		{
			greaterTail->next = cur;
			cur = cur->next;
			greaterTail = greaterTail->next;
		}
	}
	lessTail->next = greaterGuard->next;
	greaterTail->next = NULL;
	pHead = lessGuard->next;
	free(greaterGuard);
	greaterGuard = NULL;
	free(lessGuard);
	lessGuard = NULL;
	return pHead;
}

7.链表的回文结构 

 

//链表的回文结构
//方法一:找中间结点翻转链表
struct ListNode* middleNode(struct ListNode* head)
{
	struct ListNode* slow = head;
	struct ListNode* fast = head;
	while (fast && fast->next)
	{
		slow = slow->next;
		fast = fast->next->next;
	}
	return slow;
}
struct ListNode* reverseList(struct ListNode* head)
{
	struct ListNode* prev = NULL;
	struct ListNode* cur = head;
	struct ListNode* next = NULL;
	while (cur)
	{
		next = cur->next;
		cur->next = prev;
		prev = cur;
		cur = next;
	}
	return prev;
}
bool chkPalindrome(struct ListNode* head)
{
	struct ListNode* mid = middleNode(head);
	struct ListNode* rmid = reverseList(mid);
	while (head && rmid)
	{
		if (head->val != rmid->val)
			return false;
		head = head->next;
		rmid = rmid->next;
	}
	return true;
}
//方法二:
struct ListNode* reverseList(struct ListNode* head)
{
	struct ListNode* prev = NULL;
	struct ListNode* cur = head;
	struct ListNode* next = NULL;
	while (cur)
	{
		next = cur->next;
		cur->next = prev;
		prev = cur;
		cur = next;
	}
	return prev;
}
bool isPalindrome(struct ListNode* head)
{
	struct ListNode* cur = head;
	struct ListNode* copyGuard = (struct ListNode*)malloc(sizeof(struct ListNode));
	copyGuard->next = NULL;
	struct  ListNode* copyTail = copyGuard;
	while (cur)
	{
		struct ListNode* newnode = (struct ListNode*)malloc(sizeof(struct ListNode));
		newnode->val = cur->val;
		copyTail->next = newnode;
		copyTail = copyTail->next;
	}
	copyTail->next = NULL;
	struct ListNode* rhead = reverseList(copyGuard->next);
	while (rhead || head)
	{
		if (rhead->val != head->val)
		{
			return false;
		}
		rhead = rhead->next;
		head = head->next;
	}
	free(copyGuard);
	copyGuard = NULL;
	return true;
}

8.相交链表 

//方法一:
struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB) 
{
    struct ListNode* curA = headA;
	struct ListNode* curB = headB;
	while(curA != NULL)
    {
        while(curB != NULL)
        {
            if(curA == curB)
            {
                return curA;
            }
            curB = curB->next;
        }
        curB = headB;
        curA = curA->next;
    }
	return NULL;
}
//方法二:
struct ListNode* getIntersectionNode(struct ListNode* headA, struct ListNode* headB)
{
	if (headA == NULL || headB == NULL)
	{
		return NULL;
	}
	struct ListNode* curA = headA;
	struct ListNode* curB = headB;
	int lenA = 1;
	while(curA->next)
	{
		curA = curA->next;
		lenA++;
	}
	int lenB = 1;
	while (curB->next)
	{
		curB = curB->next;
		lenB++;
	}
	if (curA != curB)
	{
		return NULL;
	}
	struct ListNode* longList = headA;
	struct ListNode* shortList = headB;
	if (lenA < lenB)
	{
		longList = headB;
		shortList = headA;
	}
	int gap = abs(lenA - lenB);
	while (gap--)
	{
		longList = longList->next;
	}
	while (longList != shortList)
	{
		longList = longList->next;
		shortList = shortList->next;
	}
	return longList;
}

9.环形链表 

 

 

//环形链表
//快慢指针法:slow进环以后 fast开始追赶slow 
bool hasCycle(struct ListNode* head)
{
	struct ListNode* fast = head;
	struct ListNode* slow = head;
	while (fast && fast->next)
	{
		fast = fast->next->next;
		slow = slow->next;
		if (slow == fast)
		{
			return true;
		}
	}
	return false;
}

10.环形链表II

//环形链表II
//方法一:公式证明推导
struct ListNode* detectCycle(struct ListNode* head)
{
	struct ListNode* slow = head;
    struct ListNode* fast = head;
	while (fast && fast->next)
	{
		slow = slow->next;
		fast = fast->next->next;
		if (slow == fast)
		{
			struct ListNode* meet = slow;
			while (meet != head)
			{
				meet = meet->next;
				head = head->next;
			}
			return meet;
		}
	}
	return NULL;
}
//方法二:转换成相交问题
struct ListNode* getIntersectionNode(struct ListNode* headA, struct ListNode* headB)
{
	if (headA == NULL || headB == NULL)
	{
		return NULL;
	}
	struct ListNode* curA = headA, * curB = headB;
	int lenA = 1;
	//找尾结点
	while (curA->next)
	{
		curA = curA->next;
		lenA++;
	}
	int lenB = 1;
	while (curB->next)
	{
		curB = curB->next;
		lenB++;
	}
	if (curA != curB)
	{
		return NULL;
	}
	struct ListNode* longList = headA, * shortList = headB;
	if (lenA < lenB)
	{
		longList = headB;
		shortList = headA;
	}
	//长的链表先走差距步
	int gap = abs(lenA - lenB);
	while (gap--)
	{
		longList = longList->next;
	}
	//同时走找交点
	while (longList != shortList)
	{
		longList = longList->next;
		shortList = shortList->next;
	}
	return longList;
}
struct ListNode* detectCycle(struct ListNode* head)
{
	struct ListNode* slow = head;
	struct ListNode* fast = head;
	while (fast && fast->next)
	{
		slow = slow->next;
		fast = fast->next->next;
		if (slow == fast)
		{
			struct ListNode* meet = slow;
			struct ListNode* next = meet->next;
			meet->next = NULL;
			struct ListNode* entryNode = getIntersectionNode(head, next);
			meet->next = next;
			return entryNode;
		}
	}
	return NULL;
}

11.复制带随机指针的链表

//复制带随机指针的链表
struct Node
{
	int val;
	struct Node* next;
	struct Node* random;
};
struct Node* copyRandomList(struct Node* head)
{
	//1.插入copy结点
	struct Node* cur = head;
	struct Node* copy = NULL;
	struct Node* next = NULL;
	while (cur)
	{
		next = cur->next;
		copy = (struct Node*)malloc(sizeof(struct Node));
		copy->val = cur->val;
		cur->next = copy;
		copy->next = next;
		cur = next;
	}
	//2.更新random
	cur = head;
	while (cur)
	{
		copy = cur->next;
		if (cur->random == NULL)
		{
			copy->random = NULL;
		}
		else
		{
			copy->random = cur->random->next;
		}
		cur = cur->next->next;
	}
	//3.copy结点要解下来链接在一起 恢复原链表
	struct Node* copyHead = NULL;
	struct Node* copyTail = NULL;
	cur = head;
	while (cur)
	{
		copy = cur->next;
		next = copy->next;
		if (copyTail == NULL)
		{
			copyHead = copyTail = copy;
		}
		else
		{
			copyTail->next = copy;
			copyTail = copyTail->next;
		}
		//恢复原链表链接
		cur->next = next;
		cur = next;
	}
	return copyHead;
}

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值