小伙伴们,大家好,我们又见面了,废话不多说,直接进入正片。
空间复杂度的概念
大白话
算法在运行时所展用的空间,如果还是不太理解,请看下面这个图
看到画圈的部分了吗,当然哈,这只是举个通俗易懂的例子,方便大家理解而已,它的大O表示方法与时间复杂度的差不多,因此,这里不再举例介绍了。
那么本篇文章的主要内容除了简单讲一下空间复杂度外,还会再讲几道例题,让大家能够更好理解和巩固这个知识点。
例题1:
上一篇文章中已经介绍了两种思路:想必大家还记得第一种思路是暴力解法,但是被限制了。因此讲了第二种思路,而第二种思路是使用了三段逆置,但是三段逆置对于刚学的小伙伴来说不容易想到,因此我们今天来讲一下第三种思路空间复杂度
思路:
源代码:
void previous(int* nums, int numsSize, int k, int* arr)
{
k %= numsSize;
int n =numsSize;
memcpy(arr, nums + n - k, sizeof(int) * k);
memcpy(arr + k, nums, sizeof(int) * (n - k));
memcpy(nums, arr, sizeof(int) * (n));
}
void rotate(int* nums, int numsSize, int k) {
int arr[numsSize];
previous(nums, numsSize, k, arr);
}
例题2:
思路:
设置快慢指针,快指针一次走两个单位,慢指针一次走一个单位。并通过循环实现,当快指针跳出循环时返回慢指针的值
思路视频:
源代码:
typedef struct ListNode ln;
int kthToLast(struct ListNode* head, int k){
ln* fast,* slow;
fast = head;
slow = head;
while(k--)//在fast和slow开始移动前先固定好fast新的起点位置
{
fast = fast->next;
}
while(fast)
{
fast = fast->next;
slow = slow->next;
}
return slow->val;
}
例三:
情况分析
相信看到这题的小伙伴们,脑海中浮现的相交一定和如下图一样
那么,我们从一开始学的链表开始思考这样对不对呢?或许已经有小伙伴们已经忘记链表的结构体里的元素了吧,没事忘了咱就复习一下。为了方便大家回忆,我已经将我们一开始学的链表结构体内含有的元素图放在下面啦。
结构体内是只有一个指向后面一个节点的指针哦。
所以,小伙伴们是否已经明白,我们的第一个想法为什么是错误的了吗?
那么正确的图其实题目里已经给我们画好了,那么我们现在开始讲一下这题的思路吧。
思路:
源代码:
typedef struct ListNode ln;
struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB) {
ln* curA = headA, * curB = headB;
int lenA = 1, lenB = 1;
while(curA)
{
curA = curA->next;
++lenA;
}
while(curB)
{
curB = curB->next;
++lenB;
}
if(curA != curB)
{
return NULL;
}
int yushu = abs(lenA - lenB);
ln* longlist =headA,* shortlist = headB;//使用了假设法
if(lenA < lenB)
{
longlist =headB, shortlist = headA;//若假设错误,则修正
}
while(yushu--)
{
longlist = longlist->next;
}
while(longlist != shortlist)
{
longlist = longlist->next;
shortlist = shortlist->next;
}
return shortlist;
}
今天的内容就先到这,如若对文章中的代码有所疑惑,欢迎小伙伴们在评论区留言,我们下期再见。