算法刷题 DAY4

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

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
struct ListNode* swapPairs(struct ListNode* head) {
     struct ListNode *dummy_head=( struct ListNode *)malloc(sizeof( struct ListNode ));
dummy_head->next=head;//cur指向两个交换结点的前一个结点→使用dummy_head
 struct ListNode *cur=dummy_head,*left,*right;//left为中间结点的左边结点

 while(cur->next&&cur->next->next){//结点个数为奇数时,最后一个结点不用反转
     //先判断cur->next在判断cur->next->next 不用容易空指针异常
     left=cur->next;
     right=cur->next->next->next;
     cur->next=cur->next->next;
     cur->next->next=left;
     left->next=right;
     cur=cur->next->next;
 }

return dummy_head->next;//next才是真正的头指针
}

19.删除链表倒数第N个节点

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
struct ListNode* removeNthFromEnd(struct ListNode* head, int n) {
    struct ListNode* dummy_head=(struct ListNode* )malloc(sizeof(struct ListNode ));
    dummy_head->next=head;
    struct ListNode* fast=dummy_head,*slow=dummy_head;
    n++;
    //删除倒数第n个:fast先走n+1步,然后fast,slow同时移动直到fast指向null;最后slow指向待删除结点的前驱
    while(fast&&n--){
        fast=fast->next;
    }

    while(fast){
        fast=fast->next;
        slow=slow->next;
    }

    slow->next=slow->next->next;

    return dummy_head->next;
}

面试题 02.07. 链表相交

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB) {
    //×  struct ListNode *short,*long;//关键词不可当名字
    struct ListNode *l,*s;//分别表示长的和短的链表
    
    int lenA=0,lenB=0,gap=0;//gap表长度差
    l=headA;
    printf("1");//用于测试时间超过,看哪一步出现了死循环
    while(l){
        l=l->next;
        lenA++;
    }
    printf("1");
    l=headB;
    while(l){
        l=l->next;
        lenB++;
    }
printf("1");//用于测试时间超过,看哪一步出现了死循环
if(lenA>=lenB){
    gap=lenA-lenB;
    l=headA;
    s=headB;
}
else{
    gap=lenB-lenA;
    l=headB;
    s=headA;   
}
printf("1");//用于测试时间超过,看哪一步出现了死循环
while(gap--){//对齐
        l=l->next;
       
    }
 //printf("here %d %d",l->val,s->val);//测试l,s是否对齐
while(l){
    if(l==s) return l;交点不是数值相等,而是指针相等;不能写成l->val==s->val
    l=l->next;
    s=s->next;
   
}
printf("1");//用于测试时间超过,看哪一步出现了死循环
    return NULL;//NULL只能大写

}

142.环形链表II

//若快指针每次走三个结点,则可能跳过慢指针→每次走两个结点
//快指针至少已经在环里转了一圈才能追到慢指针
//慢指针走一圈时,快指针已经转了两圈→慢指针转了一定小于等于一圈

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

  struct ListNode *fast=head,*slow=head;
  while(fast&&fast->next){//避免空指针问题
      fast=fast->next->next;
      slow=slow->next;

      if(fast==slow){//相遇→有环
          struct ListNode *index1=head,*index2=fast;
          while(index1!=index2){
              index1=index1->next;
              index2=index2->next;
          }
          return index1;//环入口
      }
  }  

  return NULL;//没有环
}

你可能感兴趣的:(算法,c语言)