天天看點

Golang學習之路 - LeetCode-Go-Learning 第四題.尋找兩個有序數組的中位數4. Median of Two Sorted Arrays

Golang 基礎

  • [4. Median of Two Sorted Arrays](https://leetcode.com/problems/median-of-two-sorted-arrays/)
    • 題目
    • 解題思路
    • 解決方案
      • 1. append
      • 2. 非append 自己合并
      • 3. 4ms 解決範例
      • 參考編寫測試程式
    • 總結

鳴謝: LeetCode-In-Go

4. Median of Two Sorted Arrays

題目

There are two sorted arrays nums1 and nums2 of size m and n respectively.

Find the median of the two sorted arrays. The overall run time complexity should be O(log (m+n)).

Example 1:

nums1 = [1, 3]
nums2 = [2]
The median is 2.0
           

Example 2:

nums1 = [1, 2]
nums2 = [3, 4]
The median is (2 + 3)/2 = 2.5
           

解題思路

輸入兩個已經排序好的整數切片,合并兩個切片,傳回合并後切片的中位數。

是以,題目的關鍵是,如何高效地合并切片。

個人認為的解題步驟可以分為:

  1. 判斷并合并兩個數組,一個個元素來處理,不要直接使用append合并兩個數組
  2. 合并之後,補全每個數組還剩下的部分,解決兩個數組長短不一的問題
  3. 判斷計算結果的長度,根據奇偶性來處理傳回結果。

解決方案

1. append

直接用append方法進行合并,然後使用sort方法對内容進行排序,這種方式的效率不高。

具體實作的代碼如下:

// Solution by Panda.

// 生成一個新的數組,然後判斷長度奇偶數,取中間值。
func findMedianSortedArrays(nums1 []int, nums2 []int) float64 {
    if len(nums1) == 0 {
        if len(nums2) % 2 == 0 {
            return float64((nums2[len(nums2)/2] + nums2[len(nums2)/2 - 1])) / 2.0
        } else {
            return float64(nums2[len(nums2)/2])
        }
    }
    if len(nums2) == 0 {
        if len(nums1) % 2 == 0 {
            return float64((nums1[len(nums1)/2] + nums1[len(nums1)/2 - 1])) / 2.0
        } else {
            return float64(nums1[len(nums1)/2])
        }
    }
    nums := append(nums1, nums2...)
    // 對數組進行排序
    sort.Ints(nums)
    if len(nums) % 2 == 0 {
        return float64((nums[len(nums)/2] + nums[len(nums)/2 - 1])) / 2.0
    } else {
        return float64(nums[len(nums)/2])
    }
}
           
Golang學習之路 - LeetCode-Go-Learning 第四題.尋找兩個有序數組的中位數4. Median of Two Sorted Arrays

2. 非append 自己合并

下面這種自己合并的效率和本身的append差不多。

// Solution by Panda.

// 生成一個新的數組,然後判斷長度奇偶數,取中間值。
func findMedianSortedArrays(nums1 []int, nums2 []int) float64 {
    nums := combine(nums1, nums2)
    return medianOf(nums)
}

func combine(mis, njs []int) []int {
    lenMis, i := len(mis), 0
    lenNjs, j := len(njs), 0
    res := make([]int, lenMis+lenNjs)
    
    for k := 0; k < lenMis+lenNjs; k++ {
        if i == lenMis || 
        (i < lenMis && j < lenNjs && mis[i] > njs[j]) {
            res[k] = njs[j]
            j++
            continue
        }
        
        if j == lenNjs ||
        (i < lenMis && j < lenNjs && mis[i] <= njs[j]) {
            res[k] = mis[i]
            i++
        }
    }
    
    return res
}

func medianOf(nums []int) float64 {
    l := len(nums)
    
    if l == 0 {
        panic("切片長度為0, 無法求解中位數.")
    }
    
    if l%2 == 0 {
        return float64(nums[l/2]+nums[l/2-1]) / 2.0
    }
    
    return float64(nums[l/2])
}
           
Golang學習之路 - LeetCode-Go-Learning 第四題.尋找兩個有序數組的中位數4. Median of Two Sorted Arrays

3. 4ms 解決範例

func findMedianSortedArrays(nums1 []int, nums2 []int) float64 {
    var newArray []int
    i:=0
    j:=0
    for ; i<len(nums1)&&j<len(nums2);{
        if nums1[i]<nums2[j] {
            newArray=append(newArray, nums1[i])
            i++
        } else if nums1[i]==nums2[j] {
            newArray=append(newArray, nums1[i])
            newArray=append(newArray, nums2[j])
            i++
            j++
        } else {
            newArray=append(newArray, nums2[j])
            j++
        }
    }
    if i < len(nums1) {
        newArray = append(newArray, nums1[i:len(nums1)]...)
    }
    if j < len(nums2) {
        newArray = append(newArray, nums2[j:len(nums2)]...)
    }
    length := len(newArray)
    if len(newArray) % 2 == 0{
        return float64((newArray[length/2-1] + newArray[length/2]))/2
    } else {
        return float64(newArray[length/2])
    }
    
}
           

參考編寫測試程式

package problem0004

import (
	"testing"

	"github.com/stretchr/testify/assert"
)

type para struct {
	one []int
	two []int
}

type ans struct {
	one float64
}

type question struct {
	p para
	a ans
}

func Test_OK(t *testing.T) {
	ast := assert.New(t)

	qs := []question{
		question{
			p: para{
				one: []int{1, 3},
				two: []int{2},
			},
			a: ans{
				one: 2,
			},
		},
		question{
			p: para{
				one: []int{1, 3},
				two: []int{2, 4},
			},
			a: ans{
				one: 2.5,
			},
		},
	}

	for _, q := range qs {
		a, p := q.a, q.p
		ast.Equal(a.one, findMedianSortedArrays(p.one, p.two), "輸入:%v", p)
	}

	ast.Panics(func() { findMedianSortedArrays([]int{}, []int{}) }, "對空切片求中位數,卻沒有panic")
}

           

總結

分步驟完成程式。