今天的内容是链表
文章目录
- 题解
- 补充(五月)
- [1290. 二进制链表转整数](https://leetcode.cn/problems/convert-binary-number-in-a-linked-list-to-integer/)
- [237. 删除链表中的节点](https://leetcode.cn/problems/delete-node-in-a-linked-list/)
- [剑指 Offer II 024. 反转链表](https://leetcode.cn/problems/UHnkqh/)
- [1019. 链表中的下一个更大节点](https://leetcode.cn/problems/next-greater-node-in-linked-list/)
题解
328. 奇偶链表
思路:先定义一个移动指针cur,然后偶数的头节点head_odd,奇数节点的下一个节点head_n,偶数节点的下一个odd_n,然后进行链接,进入循环,cur不为空,让cur向后移动一个单位,然后奇数节点链接,判断是否为空,防止head_n移动到空指针,对后面的链接找不到前一个节点了,所以if(cur==NULL)直接跳出循环。
简单思路就是先将奇数节点链接起来,偶数节点链接起来,然后用奇数的尾节点连接到偶数节点的头上。如果奇数节点最后一个节点的下一两个节点为NULL,那直接跳出循环。偶数节点不用处理尾节点,因为无论何种情况都会指向NULL
struct ListNode* oddEvenList(struct ListNode* head){
if(head==NULL)
{
return NULL;
}
struct ListNode* head_odd = head->next;
struct ListNode* cur = head->next;
struct ListNode* head_n = head;
struct ListNode* odd_n = head_odd;
while(cur)
{
cur = cur->next;
head_n->next = cur;
if(cur==NULL)
break;
head_n = cur;
cur = cur->next;
odd_n->next = cur;
odd_n = cur;
}
head_n->next = head_odd;
return head;
}
725. 分隔链表
思路:先求出链表长度,a = len/k;b = len%k,前b个长度是a+1,后k-b个是a。循环拆分即可
注意,在改变变量b之前要将k-=b,在改变头指针之前将头指针拷贝,防止出现全都是NULL的情况。
struct ListNode** splitListToParts(struct ListNode* head, int k, int* returnSize){
struct ListNode** ans = (struct ListNode**)calloc(k,sizeof(struct ListNode*));
*returnSize = k;
int len = 0;
struct ListNode* phead = head;
while(phead)
{
phead = phead->next;
len++;
}
int a = len/k;
int b = len%k;
int i =0;
k-=b;
while(b--)
{
//前b个是a+1的长度
int count = a+1-1;
ans[i++] = head;
while(head!=NULL && count--)
{
head = head->next;
}
if(head!=NULL)
{
struct ListNode* next = head->next;
head->next = NULL;
head = next;
}
}
while(k-->0)
{
//后k-b个是a的长度
int count = a-1;
ans[i++] = head;
while(head!=NULL && count--)
{
head = head->next;
}
if(head!=NULL)
{
struct ListNode* next = head->next;
head->next = NULL;
head = next;
}
}
return ans;
}
817. 链表组件
思路:先将nums映射到哈希,然后遍历链表到哈希表里查找,如果能找到,flag置为1,找不到则说明连续以及断开了,判断flag是不是1,是则说明前面一段连续了cnt++,走出链表之后再进行一次判断,flag为1,说明到链表的最后一个节点都有一段连续的,cnt再次++。
int numComponents(struct ListNode* head, int* nums, int numsSize){
int hash[10010] = {0};
int cnt = 0;
int flag = 0;
for(int i =0;i<numsSize;i++)
{
++hash[nums[i]];
}
while(head)
{
if(hash[head->val]!=0)
{
flag = 1;
}
else
{
if(flag==1)
cnt++;
flag = 0;
}
head = head->next;
}
if(flag==1)
cnt++;
return cnt;
}
补充(五月)
1290. 二进制链表转整数
思路:模拟二进制位:先将取出来的二进制位向左移动一位,然后再或上新取下来的这一位,将最低位更新。
int getDecimalValue(struct ListNode* head){
int ans = 0;
while(head!=NULL)
{
ans = (ans<<1)|head->val;
head = head->next;
}
return ans;
}
237. 删除链表中的节点
思路:先定义一个头指针保存前一个节点,当node->next到NULL的时候,prev指向倒数第二个节点,然后将prev的val改成node的val再及将prev的next置NULL即可。
void deleteNode(struct ListNode* node) {
struct ListNode* prev = node;
while(node->next!=NULL)
{
prev->val = node->val;
prev = node;
node = node->next;
}
prev->val = node->val;
prev->next= NULL;
}
剑指 Offer II 024. 反转链表
思路:翻转指针法:定义一个cur指向head的next,然后将head的next置为空,进入循环,cur不为空循环继续,创建一个next记录cur的next,然后进行链接,将cur的next指向head,将head移动到cur,cur移动到next,当最后一次cur移动到空之后,head的位置就是最后一个节点,也就是新的头。
struct ListNode* reverseList(struct ListNode* head){
if(head==NULL)
{
return NULL;
}
struct ListNode* cur = head->next;
head->next =NULL;
while(cur)
{
struct ListNode*next = cur->next;
cur->next = head;
head = cur;
cur = next;
}
return head;
}