链表内区间反转
这是代码
typedef struct ListNode listnode;
struct ListNode* reverseBetween(struct ListNode* head, int m, int n ) {if (head == NULL) {return NULL;}listnode* findhead = head;listnode* findtail = head;listnode* prev = NULL;int count1 = m;int count2 = n;for (int i = 1; i < count1; i++) {prev = findhead;findhead = findhead->next;}for (int j = 1; j < count2; j++) {findtail = findtail->next;}listnode* p1 = findhead;listnode* p2 = p1->next;listnode* p3 = p2->next;while (p1 != findtail) {p2->next = p1;p1 = p2;p2 = p3;if (p3) {p3 = p3->next;}}if (prev) {prev->next = p1; } else {head = p1; }findhead->next = p2; return head;
}
这道题我们的思路是先找到要反转的区间的范围,在通过改变链表指针的指向来反转链表,在把反转链表的头节点和尾节点与原链表相连,我们来画图看看
我们这里通过两个for循环来找到了区间,找m的时候需要存储上一个节点,因为我们要反转完链表之后,需要把新反转的链表链接到原链表上所以要创建一个prev变量来存放上一个节点。接下来就是反转链表了,p1就是反转链表的头节点我们要用一个while循环来控制p1当p1不等于要反转的区间的尾节点,这里个反转链表的思路是重点。
接下来就是链接链表了,这时候我们反转完的头节点应该是p1我们就把我们存放的prev节点的下一个节点->p1
然后把我们原来的头节点2的下一个节点指向p2.
这样我们就完成反转了,
if (prev) {prev->next = p1; } else {head = p1; }
这段代码就是判断特殊情况的,当prev为空的时候,就证明这个反转区间就是从链表头开始的,链表头节点就是反转链表的开始。