142.环形链表II
思路这题要用到数学的思路,根据141.环形链表,我们能够知道快慢指针可以判断它是否是环形,并且能够得出相遇的位置,现在我们知道头结点和相遇的地点,我们画图解析一下 1假设a为头结点,b为入口,c为相遇点 先画一圈的展示 路程: s : ab+bc f : ab+n*环+bc 当s绕多于一圈时我们把s和f减掉多的圈数,这样就可以只考虑上图所示,不用考虑那么多 又有: 2s=f 所以: 2ab+2bc=ab+n(bc+cb)+bc 转为: 12---> ab+bc=n(bc+cb)--->...
141.环形链表
思路 这题要用到快慢指针 一个环形链表我们定义一个fast和一个slow,让他们开始向前遍历,fast走得快slow走得慢,如果是环形链表,那么他们肯定会相遇,如果不是那么fast总会走到null 代码123456789101112131415bool hasCycle(struct ListNode *head) { if(head==NULL){ return false; } struct ListNode*fast=head->next; struct ListNode*slow=head; while(fast!=NULL&&fast->next!=NULL){ fast=fast->next->next; slow=slow->next; if(fast==slow){ return true; } } return...
206.反转链表
解题非常简单粗暴,数据结构有教,这里就画个图解释一下 123456789101112131415struct ListNode* reverseList(struct ListNode* head) { if(head==NULL){ return 0; } struct ListNode* pre=NULL; struct ListNode* curr=head; struct ListNode* temp=NULL; while(curr!=NULL){ temp=curr->next; curr->next=pre; pre=curr; curr=temp; } return pre;} 关键就在于将c指向p,然后三者后移
25.K个一组反转链表
思路想了两节课终于想出来了 在此之前我们先复习一下反转链表 [206.反转链表 | ᕙ(• ॒ ູ•)ᕘ欢迎光临ᕙ(`▿´)ᕗ](https://cotton-star.github.io/2024/11/04/leedcode刷题之旅/206. 反转链表/) 我们需要一个哑结点p,一组的开头start,一组的结尾end,以及下一组的开头k 代码1234567891011121314151617181920212223242526272829303132333435363738 struct ListNode* reverseList(struct ListNode* head) { if(head==NULL){ return 0; } struct ListNode* pre=NULL; struct ListNode* curr=head; struct ListNode* temp=NULL; while(curr!=NULL){ ...
24. 两两交换链表中的节点
交换节点24. 两两交换链表中的节点 交换节点嘛,来一个哑结点再来三个指针pre p q 1234这个是交换的步骤pre->next=q;p->next=q->next;q->next=p; 1234这个是往下的步骤pre=p;p=p->next;q=q->next; 这里要注意的是在每次循环中不能直接q=q->next,否则有可能让q指到null->next去 因此只要在循环开始处再定义就可以防止错误 代码12345678910111213141516171819struct ListNode* swapPairs(struct ListNode* head) { struct ListNode*dummy=malloc(sizeof(struct ListNode)); dummy->val=0; dummy->next=head; struct ListNode*pre=dummy; struct ListNode*p=head; ...
19.删除链表倒数第N个结点
思路链表题三套路:哑结点,栈,快慢指针 用栈的话空间复杂度会比较高 这题就用哑结点dummy和快慢指针来实现 123哑结点是防止特殊情况,把头结点删除了因为删除一个结点我们需要知道它的前驱结点就可以了先让slow指向dummy,fast指向head,等下要让他们一起走,让slow最终指向删除结点的前驱节点,因此fast的位置得找好,先让fast到开始往后n处 while(fast)这样slow就刚好到达删除结点的前一个结点 代码12345678910111213141516struct ListNode* removeNthFromEnd(struct ListNode* head, int n) { struct ListNode*dummy=malloc(sizeof(struct ListNode)); dummy->val=0; dummy->next=head; struct ListNode*slow=dummy; struct ListNode*fast=head; for(int...
977.有序数组的平方
可以直接平方快排,时间复杂度就是n+n*logn; 这里用上前后指针可以很好地解决; 原数组是递增的,因此最大的要么在最左边,要么在最右边 我们只需要比较两者大小,塞进新数组(从后往前塞),然后原数组的左指针后移或者右指针前移 当left>right时停止(相等的时候也要把那个数搞进新数组) 最终代码: 123456789101112int* sortedSquares(int* nums, int numsSize, int* returnSize) { int* res=malloc(numsSize*sizeof(int)); int index=numsSize-1; int left=0; int right=numsSize-1; while(left<=right){ ...
9.回文数
9.回文数 这题把数字看作字符串肯定是好解决的,题解有绝妙的思路 1234老样子先排除:x负数不行,尾数为0不行if(x<0||(x%10==0&&x!=0)) return false; 1234567891011121314151617看 12321 这个数字 假设他为x现在我们要开始倒序他 把 x%10 把个位拿出来再把 x=x/10 准备进行下一步操作 那么最后两位倒序就是: re=(x%10)*10+x%10; 之后就是再次进行操作: x=x/10; re=re*10+x%10; 停止条件判断: 我们要判断逆序的是否等于正序的,有奇数和偶数两种可能 比如 12321 我们re=123的时候就够了 比如 1221 我们re=12 因此就是当正序的x=re||re/10为 True 当正序的<=逆序,也就是x<=re时就可以停止了 最终代码 1234567891011bool isPalindrome(int x) { if(x<0||(x%10==0&&x!=0)){ ...
209.长度最小的子数组
暴力12345678910111213141516171819202122int minSubArrayLen(int target, int* nums, int numsSize) { int min=10000; for(int i=0;i<numsSize;i++){ if(nums[i]>=target){ return 1; break; } int sum=nums[i]; for(int j=i+1;j<numsSize;j++){ sum+=nums[j]; if(sum>=target&&(j-i+1)<min){ min=j-i+1; break; } } } ...
哈希表用uthash实现
uthash头文件: 1#include "uthash.h" 使用之前要创建一个结构体 12345struct HashTable{ int key; int value; UT_hash_handle hh;}; 12hh是内部使用的hash处理句柄,必须在该结构体中定义该变量。 Uthash所实现的hash表中,可以通过结构体成员hh的hh.prev和hh.next获取当前节点的上一个节点和下一个节点 之后定义一个哈希表指针 1struct hashTable* hashtable; 添加 向hashtable中添加数据 key是int 使用HASH_ADD_INT key是字符串 使用HASH_ADD_STR key是指针 使用HASH_ADD_PTR 1HASH_ADD_INT(hashtable,key,tmp),插入tmp结点 替换 如果key是int,可以使用 HASH_REPLACE_INT 查找 如果key是int,可以使用...








