(8) 返回链表的中间节点
-
解题思路:
使用快慢指针,快指针走两步,慢指针走一步,快指针指向空,慢指针所指向的节点就是中间节点
/** * Definition for singly-linked list. * struct ListNode { * int val; * struct ListNode *next; * }; */ //使用快慢指针,快指针走两步,慢指针走一步,快指针指向空,慢指针所指向的节点就是中间节点 struct ListNode* middleNode(struct ListNode* head) { //定义两个指针 struct ListNode* fast = head; struct ListNode* slow = head; //循环条件判断:fast->next不能放在前面,因为如果链表是偶数个节点,fast最后一次会直接走到空 while(fast && fast->next){ slow = slow->next; fast = fast->next->next; } return slow; }
(9)输入一个链表,输出该链表中倒数第k个结点
-
解题思路:
定义两个前后指针,之间相差k步,当后指针指为空的时候,前指针所指向的节点就是目标节点。
/** * Definition for singly-linked list. * struct ListNode { * int val; * struct ListNode *next; * }; */ //定义两个前后指针,之间相差k步,当后指针指为空的时候,前指针所指向的节点就是目标节点。 int kthToLast(struct ListNode* head, int k) { struct ListNode *first = head; struct ListNode *last = head; // 先让last向前移动k步 for (int i = 0; i < k; i++) { if (last == NULL) { return -1; // 处理k大于链表长度的情况 } last = last->next; } // 然后first和last一起移动,直到last为NULL while (last != NULL) { first = first->next; last = last->next; } return first->val; }
(10)合并两个有序链表
-
解题思路:
循环遍历比较两个链表,谁小谁就尾插到新链表当中,谁尾插谁加加,最后再判断一下有没有没比的,全放在新链表的最后
/** * Definition for singly-linked list. * struct ListNode { * int val; * struct ListNode *next; * }; */ struct ListNode* mergeTwoLists(struct ListNode* list1, struct ListNode* list2) { // 创建一个虚拟头节点 struct ListNode dummy; struct ListNode* tail = &dummy; dummy.next = NULL; // 循环遍历比较 while(list1 && list2){ if(list1->val < list2->val){ tail->next = list1; list1 = list1->next; } else { tail->next = list2; list2 = list2->next; } tail = tail->next; } // 连接剩余节点 if(list1 != NULL){ tail->next = list1; } else { tail->next = list2; } return dummy.next; }