day21

【面试题 02.07. 链表相交】

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    int listLength(ListNode *head) { //返回链表结点总个数
        ListNode *temp = head;
        int result = 0;
        while (temp != nullptr) { 
            result++;
            temp = temp->next;
        }
        return result;
    }
    ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
        int ALength = listLength(headA);
        int BLength = listLength(headB); 
        ListNode *shortList = ALength < BLength ? headA : headB;
        ListNode *longList = ALength >= BLength ? headA : headB;
        if(shortList == nullptr || longList == nullptr)
            return nullptr;
        int extraNode = ALength >= BLength ? (ALength - BLength) : (BLength - ALength) ;
        while (extraNode) {
            longList = longList->next;
            extraNode--;
        }

        while (shortList != nullptr) {
            if (shortList == longList) {
                return shortList;
            }
            shortList = shortList->next;
            longList = longList->next;
        }
        return nullptr;
    }
};
  • 四十分钟好像,较慢,一开始没思路,双指针法中类似这种 fast先走 然后fast和slow一起走的题型我都想不到这个思路

  • 有了提示思路后 代码有几个问题

    • 关于while循环 以下两段代码等价 即while是先判断循环条件逻辑值 再执行循环体 后进行循环条件中的运算

      while (extraNode) {
                  longList = longList->next;
                  extraNode--;
              }
      while (extraNode--) {
                  longList = longList->next; 
              }
      
      
    • 此外关于while循环 注意与if循环的判断是有次数的去别的 前者在符合条件的情况下一直执行循环体 后者在符合条件的情况下只执行一次循环体

    • 主函数 最后return 是对边界特殊值等的处理语句 不能写成short->next 因为跳出循环时short==nullptr 那么之后就千万不能取值short->next 因为这等价于nullptr->next 这是不合法的 !!!》》》》》换句话说,当你return时 需要留意可以return空 但不能return 某个对空的操作 会报错!!!老是错!!!

    • 另外关于return 没有考虑当最开始的头指针为空的情况 也就是链表本身为空 就直接返回空值 不需要再操作了!!!老是忘!!!

  • 最总要的问题是 也是我花费时间最多的 是关于对未知谁是更大更长的两元素进行操作

    • 我的思路是: 找到谁长谁短并记下来:定义一个短链表指针 取比较语句中长度小的值 同理定义一个长链表指针 取比较语句中长度较长的值;定义一个表示两链表长度差值的整形变量 取比较语句中长度长的值-长度短的值的差;》》》》》最后遇到问题了 没考虑两链表长度相同的情况 所以在前面取值的时候 其中一个添加上等于号

      ListNode *shortList = ALength < BLength ? headA : headB;
      ListNode *longList = ALength >= BLength ? headA : headB;
      int extraNode = ALength >= BLength ? (ALength - BLength) : (BLength - ALength) ;
      
      	while (extraNode) {
                  longList = longList->next;
                  extraNode--;
      	}
      
      	while (shortList != nullptr) {
                  if (shortList == longList) {
                      return shortList;
                  }
                  shortList = shortList->next;
                  longList = longList->next;
      	}
      
    • 我之前的思路是:不管谁长谁短 两个while循环二选一移动指针就行

      while(countA -countB >0){
                  curA = curA->next;
                  countA--;
      }
      while(countB - countA >0){
                  curB = curB->next;
                  countB--;
      }
      while(curA != nullptr){
                  if(curA == curB)
                      return curA;
                  curA = curA->next;
                  curB = curB->next;
      }
      
    • 最好记得卡哥的思路:自己决定谁长谁短

      		// 让curA为最长链表的头,lenA为其长度
              if (lenB > lenA) {
                  swap (lenA, lenB);
                  swap (curA, curB);
              }
              // 求长度差
              int gap = lenA - lenB;
              // 让curA和curB在同一起点上(末尾位置对齐)
              while (gap--) {
                  curA = curA->next;
              }
              // 遍历curA 和 curB,遇到相同则直接返回
              while (curA != NULL) {
                  if (curA == curB) {
                      return curA;
                  }
                  curA = curA->next;
                  curB = curB->next;
              }
      
    • 这部分还需要 再看看消化消化
      明天继续:)

posted @ 2022-11-18 21:05  跬步瑶  阅读(26)  评论(0)    收藏  举报