[LeetCode] 4. 두 개의 질서 있 는 배열 의 중위 수 (특수 한 이분법) 를 찾 습 니 다.

10101 단어 Leetcode
m 와 n 크기 의 질서 있 는 배열 nums 1 과 nums 2 를 지정 합 니 다.이 두 질서 있 는 배열 의 중위 수 를 찾 아 알고리즘 의 시간 복잡 도 를 O (log (m + n) 로 요구 하 십시오.너 는 nums 1 과 nums 2 가 동시에 비어 있 지 않다 고 가정 할 수 있다.예시 1: nums 1 = [1, 3] nums 2 = [2] 는 중위 수 2.0 예시 2: nums 1 = [1, 2] nums 2 = [3, 4] 는 중위 수 (2 + 3) / 2 = 2.5 출처: 힘 단추 (LeetCode) 링크:https://leetcode-cn.com/problems/median-of-two-sorted-arrays 저작권 은 인터넷 에 귀속 된다.상업 전 재 는 정부 에 연락 하여 권한 을 부여 해 주 십시오. 비 상업 전 재 는 출처 를 밝 혀 주 십시오.
포인트
  • 복잡 도 는 O (log (m + n)
  • 질서 있 는 배열
  • 사고의 방향
  • 두 배열 을 하나의 배열 로 만 들 고 중위 수 를 구한다.복잡 도 에서 분석 하면 길이 m + n 의 질서 있 는 배열 이 라면 중위 의 복잡 도 O(1) 를 찾 아 직접 얻 는 length / 2 곳 이 답 이다.한편, 두 개의 질서 있 는 배열 을 하나의 질서 있 는 배열 로 조합 하 는 복잡 도 는 O(m + n) 로 제목 이 요구 하 는 복잡 도 를 초과 했다.
  • log 에서 생각 하고 log 등급 의 알고리즘 은 이분법 을 고려 할 수 있다.두 배열 은 어떻게 2 점 을 진행 합 니까?최종 답 과 두 배열 의 중위 수 관 계 를 분석 하 다. 가설 K = (n + m) / 2, 즉 중위 수의 번호 로 두 배열 의 K 번 째 큰 수 를 찾 으 면 답 을 찾 을 수 있다.우 리 는 A 와 B 수조 에 한 사람 당 K / 2 개의 숫자 를 줄 기 회 를 주 었 다.
  •            Ka
    A:----------|---------------
           1            2
           
               Kb
    B:----------|-------------------------------
          3                    4
    

    위 에 A 와 B 두 개의 질서 있 는 배열 (작은 것 부터 큰 것 까지) 이 고 세로 선 은 Ka = A[K / 2]Kb = B[K / 2] 이 라 고 가정 한다.이 네 단락 의 길 이 는 각각 L1, L2, L3, L4 이다.
    Ka 와 Kb 를 비교 하면 Ka > Kb K 는 반드시 Kb 보다 작은 부분, 즉 L3 에 떨 어 지지 않 을 것 이다.그렇다면 L1 + L2 + L4 에서 제 K - L3 개 수 를 찾 는 것 이다.매번 K / 2 단 을 제외 할 수 있 기 때문에 전체적인 복잡 도 는 K = (n + m) / 2 이다.
    코드
    double min(double a,double b){
        if(a>b)return b;
        return a;
    }
    double calKth(int a[],int n,int b[],int m,int k){
        if(n==0)
            return b[k-1];
        else if(m==0)
            return a[k-1];
        if(k==1)
            return min(a[0],b[0]);
        int ma=min(k/2,n),mb=min(k/2,m);
        if(a[ma-1]>b[mb-1]){
            return calKth(a,n,b+mb,m-mb,k-mb);
        }
        return calKth(a+ma,n-ma,b,m,k-ma);
    }
    double findMedianSortedArrays(int* nums1, int nums1Size, int* nums2, int nums2Size) {
        if((nums1Size+nums2Size)%2){
            return calKth(nums1,nums1Size,nums2,nums2Size,(nums1Size+nums2Size+1)/2);
        }
        int k1=(nums1Size+nums2Size)/2,k2=k1+1;
        return (calKth(nums1,nums1Size,nums2,nums2Size,k1)+calKth(nums1,nums1Size,nums2,nums2Size,k2))/2.0;
    }
    

    좋은 웹페이지 즐겨찾기