[LeetCode Sword Finger Offer 52] 연결된 목록은 교차합니다. 두 연결 목록의 첫 번째 공통 노드 인 단방향 연결 목록이 주어지면 교차 여부를 결정하고 교차점으로 돌아갑니다. 교차점의 정의는 노드의 값이 아니라 노드의 참조를 기반으로합니다.

학습 목표 :

목표 : Java에서 배운 지식을 능숙하게 사용


학습 내용 :

이 기사의 내용 : Java에서의 구현 : 연결 목록의 교차점


제목 설명:

두 개의 (단방향) 연결 목록이 주어지면 이들이 교차하고 교차점으로 돌아가는지 확인합니다. 교차점의 정의는 노드의 값이 아니라 노드의 참조를 기반으로합니다. 즉, 한 연결 목록의 k 번째 노드와 다른 연결 목록의 j 번째 노드가 동일한 노드 (참조가 정확히 동일 함)이면 두 연결 목록이 교차합니다.

두 개의 연결 목록을 입력하고 첫 번째 공통 노드를 찾으십시오.

다음 두 개의 연결 목록과 같은 :

여기에 사진 설명 삽입

교차점은 노드 c1에서 시작됩니다.

예 1 :

여기에 사진 설명 삽입

입력 : intersectVal = 8, listA = [4,1,8,4,5], listB = [5,0,1,8,4,5], skipA = 2, skipB = 3
출력 : 다음과 같은 노드 참조 값 = 8
입력 설명 : 교차 노드의 값은 8입니다 (두 목록이 교차하면 0이 될 수 없습니다). 각 헤더에서 시작하여 연결 목록 A는 [4,1,8,4,5]이고 연결 목록 B는 [5,0,1,8,4,5]입니다. A에서는 교차 노드 앞에 2 개의 노드가 있고 B에서는 교차
노드 앞에 3 개의 노드가 있습니다 .

예 2 :
여기에 사진 설명 삽입

입력 : intersectVal = 2, listA = [0,9,1,2,4], listB = [3,2,4], skipA = 3, skipB = 1
출력 : 값 = 2 인 노드 참조
입력 설명 : 교차 노드의 값은 2입니다 (두 목록이 교차하는 경우 0이 될 수 없음). 각 헤더에서 시작하여 연결 목록 A는 [0,9,1,2,4]이고 연결 목록 B는 [3,2,4]입니다. A에서는 교차 노드 앞에 3 개의 노드가 있고 B에서는 교차 노드 앞에 1 개의 노드가 있습니다.

예 3 :
여기에 사진 설명 삽입

입력 : intersectVal = 0, listA = [2,6,4], listB = [1,5], skipA = 3, skipB = 2
출력 : null
입력 설명 : 각 헤더에서 계산 , 연결 목록 A는 [2, 6,4], 연결 목록 B는 [1,5]입니다. 이 두 연결 목록은 교차하지 않으므로 intersectVal은 0이어야하며 skipA 및 skipB는 임의의 값이 될 수 있습니다. 설명 : 두 개의 링크 된 목록이 교차하지 않으므로 널이 리턴됩니다.

문제 해결 아이디어

두 연결 목록이 교차하는 경우 다음 그림과 같이 교차 뒤의 노드도 공통 노드 여야합니다.
여기에 사진 설명 삽입
설명 : 단일 연결 목록에는 교차가있는 한 다음 노드 옆에 포인터가 하나만 있으므로, 두 개의 연결 목록이 뒤 따릅니다. 노드는 모두 공용 노드입니다.

중요 아이디어 : 두 개의 연결 목록이 교차하는지 확인하려면 공통 노드가 있는지 확인하기 만하면됩니다. 이중 루프를 사용하여 하나씩 제외하는 것은 생각하기 쉽지만 시간이 너무 많이 걸립니다. 두 연결 목록의 교차점 뒤의 길이는 동일하므로 더 간단한 방법이 있습니다.

  • 먼저 두 연결 목록의 길이를 찾으십시오.
     int countA=0,countB=0;
       ListNode curA=headA,curB=headB;
       //循环遍历,求出链表长度
       while(curA!=null){
    
    
           curA=curA.next;
           countA++;
       }
       while(curB!=null){
    
    
           curB=curB.next;
           countB++;
       }
       //将curA和curB的位置更新至表头
       curA=headA;
       curB=headB;
  • 어떤 연결 목록이 더 긴지 확인하고 길이 차이를 찾습니다.
  • 길이가 다른 노드에 의해 처음부터 뒤로 긴 연결 목록을 순회합니다.
//判断长度,将较长的链表向后遍历长度差个节点
    if(countA>countB){
    
    
           for(int i=0;i<countA-countB;i++){
    
    
               curA=curA.next;
           }

       }else{
    
    
           for(int i=0;i<countB-countA;i++){
    
    
               curB=curB.next;
           }
       }
  • 그런 다음 두 연결 목록을 동시에 탐색하여 참조가 동일한 지 확인합니다.
//循环遍历,判断节点引用是否相同
        while(curA!=null&&curB!=null){
    
    
            if(curA==curB){
    
    
                return curA;//如果相同则返回该结点
            }
            curA=curA.next;
            curB=curB.next;
        }
        return null;//跳出while循环说明没有公共结点

구현 코드

    public static ListNode getIntersectionNode(ListNode headA, ListNode headB) {
    
    
        int countA=0,countB=0;
        ListNode curA=headA,curB=headB;
        //循环遍历,求出链表长度
        while(curA!=null){
    
    
            curA=curA.next;
            countA++;
        }
        while(curB!=null){
    
    
            curB=curB.next;
            countB++;
        }
        curA=headA;
        curB=headB;
//判断长度,将较长的链表向后遍历长度差个节点
        if(countA>countB){
    
    
            for(int i=0;i<countA-countB;i++){
    
    
                curA=curA.next;
            }

        }else{
    
    
            for(int i=0;i<countB-countA;i++){
    
    
                curB=curB.next;
            }
        }
//循环遍历,判断节点引用是否相同
        while(curA!=null&&curB!=null){
    
    
            if(curA==curB){
    
    
                return curA;//如果相同则返回该结点
            }
            curA=curA.next;
            curB=curB.next;
        }
        return null;//跳出while循环说明没有公共结点
    }

추천

출처blog.csdn.net/zhangxxin/article/details/114535073