912.排序数组

190 阅读1分钟

题目:
给你一个整数数组 nums,请你将该数组升序排列。
算法:
方法一:冒泡法
当前数字和下一个数字比较,将大的数字往后交换。交换的次数涉及的变量比较多

	change := false
	for i := 0; i < len(nums); i ++ {
		for j := 0; j < len(nums) - i - 1; j ++ {
			if nums[j] > nums[j + 1] {
				change = true
				nums[j], nums[j + 1] = nums[j + 1], nums[j]
			}
		}
		if !change {
			break
		}
	}
	return nums

方法二:插入法
左侧已排序,右侧未排序。每次从未排序数组中选择一个,插入到指定位置,插入位置开始的数组右移

func sortArray(nums []int) []int {
	for i := 1; i < len(nums); i++ {
		val := nums[i]
		j := i 
		// 找到val要插入的位置j
		for ; 0 < j; j-- {
			if nums[j-1] <= val {
				break
			}
			nums[j] = nums[j-1]
		}
		
		// 从j开始所有数字后移到i
		nums[j] = val
		// fmt.Println(nums,i,val, j)
	}
	return nums
}

方法三:选择法
选择最小/最大的交换数据开头/结尾

func sortArray(nums []int) []int {
	for i := len(nums) - 1; 1 <= i; i-- {
		max := i
		for j := 0; j < i; j++ {
			if nums[j] > nums[max] {
				max = j
			}
		}
		if max != i {
			nums[max], nums[i] = nums[i], nums[max]
		}
	}
	return nums

方法四:归并排序

数组分为2部分,左右两边都排序好,合并为一个新的有序数组

func sortArray(nums []int) []int {
	return doSort(nums, 0, len(nums) - 1)
}

func doSort(nums []int, left, right int) []int {
	if left >= right {
		return nums[left:right + 1]
	}
	mid := (left + right) / 2
	l := doSort(nums, left, mid)
	r := doSort(nums, mid + 1, right)
	return merge(l, r)
}

func merge(a, b []int) []int {
	ans := make([]int, 0)
	i, j := 0, 0
	for ; i < len(a) && j < len(b); {
		if a[i] < b[j] {
			ans = append(ans, a[i])
			i ++
		} else {
			ans = append(ans, b[j])
			j ++
		}
	}
	if i < len(a) {
		ans = append(ans, a[i:]...)
	} 
	if j < len(b) {
		ans = append(ans, b[j:]...)
	} 
	return ans
}

方法五:快速排序
不选择随机pivot过不了用例

func sortArray(nums []int) []int {
	doSort(nums, 0, len(nums) - 1)
	return nums
}

func doSort(nums []int, left, right int)  {
	if left >= right {
		return 
	}
	pivot := partion(nums, left, right)
	doSort(nums, left, pivot - 1)
	doSort(nums, pivot + 1, right)
	
}

// 对nums排序,返回index,index左右侧有序
func partion(nums []int, left, right int) int {
	randomPivot(nums, left, right)
	pivotVal := nums[right]
	pivot := left
	for j := left; j < right; j ++{
		if nums[j] < pivotVal {
			nums[pivot], nums[j] = nums[j], nums[pivot]
			pivot ++
		}
	}
	nums[pivot], nums[right] = nums[right], nums[pivot]
	return pivot
}

func randomPivot(nums []int, left, right int) {
	n := rand.Intn(right - left + 1) + left
	nums[n], nums[right] = nums[right], nums[n]
}