代码随想录算法训练营第四天 | 24. 两两交换链表中的节点

24. 两两交换链表中的节点 

每次选择2个节点进行交换,同时需要判断下一次的2个节点(3节点和4节点)的情况。

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */

void dfs(struct ListNode *head){
    if(head == NULL || head->next == NULL) {
        return ;
    }
    struct ListNode *hnext2node = head->next->next;
    struct ListNode *tmpnext = head->next;
    struct ListNode *curnode = head;
    tmpnext->next = curnode;
    if(hnext2node != NULL && hnext2node->next != NULL) {
        curnode->next = hnext2node->next;
    } else {
         curnode->next = hnext2node;
    }
    dfs(hnext2node);
}

struct ListNode* swapPairs(struct ListNode* head){
    if(head == NULL || head->next == NULL) {
        return head;
    }
    struct ListNode* ret = head->next;
    dfs(head);
    struct ListNode *out = ret;
    while(out) {
        printf("---%d\n",out->val);
        out = out->next;
    }
    return ret;

}

LCR 021. 删除链表的倒数第 N 个结点

题目比较简单,就是有几种特殊的情况需要单独进行判断一下

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
 int num = 0;
void dfs(struct ListNode *head, int n)
{
    struct ListNode *pre = head;
    int calsize = 0;
    struct ListNode *current = head;
    while(head != NULL) {
        pre = head;
        calsize++;
        if(calsize == num-n) {
            pre->next = pre->next->next;
            return ;
        }
        head = head->next;
    }
}

struct ListNode* removeNthFromEnd(struct ListNode* head, int n){
    struct ListNode *ret = head;
    num = 0;
    while(head != NULL) {
        head = head->next;
        num++;
    }
    printf("%d,%d\n",num,n);
    if(num == n && n == 1) {
        return NULL;
    }
    if(num == n) {
        return ret->next;
    }
    dfs(ret, n);
    return ret;
}

面试题 02.07. 链表相交

这个题就是用暴力法,2个for循环进行遍历查找即可

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB) {
    while(headA) {
        struct ListNode *tmpa = headA;
        struct ListNode *tmpb = headB;
     //   printf("aaaaa\n");
        while(tmpb) {
            if(tmpa == tmpb && tmpa != NULL) {
             //   printf("%d\n",tmpa->val);
                return tmpa;
            }
          //  printf("bbbbb\n");
            tmpb = tmpb->next;
        }
        if(headA != NULL) {
         //   printf("ccccc\n");
            headA = headA->next;
        }
    }
    return NULL;
}

LCR 022. 环形链表 II

这个题目有一定的技巧,1、判断是否有环很容易想到方法,但是要找到环的入口位置,就有点难度了,参考了一个卡哥的代码随想录思想。

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
struct ListNode *detectCycle(struct ListNode *head) {
    if(head == NULL) {
        return NULL;
    }
    while(1) {
        struct ListNode *firsthead = head;
        struct ListNode *secondhead = head;
        while(1) {
            if(firsthead == NULL || secondhead == NULL || secondhead->next == NULL) {
                return NULL;
            }
            firsthead = firsthead->next;
            secondhead = secondhead->next->next;

            if(firsthead == secondhead) {
                if(firsthead == NULL) {
                   return NULL;
                }
                struct ListNode *tmp1 = head;
                struct ListNode *tmp2 = firsthead;
                while(tmp1 && tmp1 != tmp2) {
                    tmp1= tmp1->next;
                    tmp2 = tmp2->next;
                }
                return tmp1;
            }
        }
          return NULL;
    }
  
}

你可能感兴趣的:(算法,链表,深度优先)