做爲一名coder,算法不只要會懂會寫,在保證結果正確的同時,還要求性能足夠高,才稱得上優秀的算法。golang
本文比較了本人用 golang
初練算法的一些 demo
,以期不斷進步,假以時日,寫出更好的算法。算法
a. 本人寫法:數組
func majorityElement1(nums []int) int { n := len(nums) for i := 0; i < n; i++ { equalNum := 1 for j := 0; j < n; j++ { if nums[i] == nums[j] && i != j { equalNum++ } if equalNum > n/2 { return nums[i] } } } return nums[0] }
b. 別人優秀寫法:app
func majorityElement2(nums []int) int { middle := len(nums) / 2 equalMap := make(map[int]int, middle) for _, v := range nums { equalMap[v] += 1 if equalMap[v] > middle { return v } } return nums[0] }
a. 本人寫法:函數
func singleNumber1(nums []int) int { n := len(nums) for i := 0; i < n; i++ { for j := 0; j < n; j++ { if nums[i] == nums[j] && i != j { break } if j == (n - 1) { return nums[i] } } } return nums[n-1] }
b. 別人優秀寫法:性能
func singleNumber2(nums []int) int { // 零和任何數異或都等於任何數, 一個數異或兩次就等於0 // 本題中除一個以外每一個元素都出現兩次 // 因此用循環異或全部數就等於 只出現一次的那個數 ret := 0 for _, v := range nums { ret ^= v } return ret }
a. 本人寫法:學習
func searchMatrix1(matrix [][]int, target int) bool { ret := false for i, _ := range matrix { if ret { break } for _, inValue := range matrix[i] { if inValue == target { ret = true break } } } return ret }
b. 別人優秀寫法:spa
func searchMatrix2(matrix [][]int, target int) bool { if len(matrix) == 0 { return false } row, col := len(matrix), len(matrix[0]) i, j := 0, col-1 for i < row && j >= 0 { if matrix[i][j] == target { return true } if matrix[i][j] > target { j-- } else if matrix[i][j] < target { i++ } } return false }
a. 本人寫法:code
func merge1(nums1 []int, m int, nums2 []int, n int) { nonZero := 0 for i, _ := range nums1 { if nums1[i] != 0 { nonZero = i break } } length := len(nums1) for i := 0; i < length; i++ { if nums1[i] == 0 { if length == 1 { nums1 = []int{} break } if i > nonZero { nums1 = append(nums1[:i], nums1[i+1:]...) i-- } length = len(nums1) } } m = len(nums1) if m <= 0 || len(nums1) == 0 { nums1 = append(nums1, nums2...) } else { for i := 0; i < m; i++ { if len(nums1) == m+n { break } for index := 0; index < n; index++ { // corner case if nums2[0] >= nums1[m-1] && i == 0 && index == 0 { nums1 = append(nums1, nums2...) break } if nums2[n-1] <= nums1[0] && i == 0 && index == 0 { nums1 = append(nums2, nums1...) break } if nums2[index] > nums1[i] { if i == len(nums1)-1 { nums1 = append(nums1, nums2[index:]...) break } i++ if index != n-1 { index-- } else { nums1 = append(nums1, nums2[n-1]) break } continue } if nums2[index] == nums1[i] { rear := append([]int{}, nums1[i+1:]...) nums1 = append(nums1[0:i+1], nums2[index]) nums1 = append(nums1, rear...) i++ continue } if nums2[index] < nums1[i] { if index == 0 && i == 0 { nums1 = append([]int{nums2[index]}, nums1...) } else { rear := append([]int{}, nums1[i:]...) nums1 = append(nums1[0:i], nums2[index]) nums1 = append(nums1, rear...) } i++ continue } } } } fmt.Println(nums1) }
b. 別人優秀寫法:排序
func merge2(nums1 []int, m int, nums2 []int, n int) { for i := 0; i < n; i++ { nums1[m+i] = nums2[i] } sort.Sort(sort.IntSlice(nums1)) fmt.Println(nums1) }
這個題目,本身花了不少時間才寫出來,看了別人的寫法後,反思本身怎麼沒有想到用 golang
自帶的排序函數 : (
因此作事情以前要先想到是否別人已經有造好的輪子(固然輪子要是已經被普遍承認的)可用,站在巨人的肩膀上才能走的更遠。
小結:
從以上例子看出,在寫算法,我目前的思路老是想着循環嵌套去實現,雖然能計算出正確的結果,但性能很低,因此須要不斷學習別人優秀的算法思路,不斷動手練習,指望之後也能夠隨手寫出優秀的算法。
祝你們週末愉快~