leetcode-pp / 91alg-7-daily-check

6 stars 0 forks source link

【Day 36 】2022-05-06 - 912. 排序数组 #39

Open azl397985856 opened 2 years ago

azl397985856 commented 2 years ago

912. 排序数组

入选理由

暂无

题目地址

https://leetcode-cn.com/problems/sort-an-array/

前置知识

 

示例 1:

输入:nums = [5,2,3,1] 输出:[1,2,3,5] 示例 2:

输入:nums = [5,1,1,2,0,0] 输出:[0,0,1,1,2,5]  

提示:

1 <= nums.length <= 50000 -50000 <= nums[i] <= 50000

yinhaoti commented 2 years ago
class Solution:
    def sortArray(self, nums: List[int]) -> List[int]:
        """
        Ideas: Count Sort
            build a large list to save occurence of num
            then enumerate it to  get result
        TC: O(n)
        SC: O(100001)
        """
        count = [0 for i in range(50000 * 2 + 1)]
        for num in nums:
            count[num + 50000] += 1

        res = []

        for i in range(len(count)):
            num = i
            occurence = count[i]
            for j in range(occurence):
                res.append(num - 50000)
        return res

    def sortArray(self, nums: List[int]) -> List[int]:
        """
        Ideas:quick sort
            https://leetcode-cn.com/problems/sort-an-array/solution/duo-chong-pai-xu-yi-wang-da-jin-kuai-pai-wgz4/
        TC: O(nlogn)
        TC: O(n*1)
        """
        def partition(arr, low, high):
            pivot_idx = random.randint(low, high)                   # 随机选择pivot
            arr[low], arr[pivot_idx] = arr[pivot_idx], arr[low]     # pivot放置到最左边
            pivot = arr[low]                                        # 选取最左边为pivot

            left, right = low, high     # 双指针
            while left < right:
                while left<right and arr[right] >= pivot:          # 找到右边第一个<pivot的元素
                    right -= 1
                arr[left] = arr[right]                             # 并将其移动到left处

                while left<right and arr[left] <= pivot:           # 找到左边第一个>pivot的元素
                    left += 1
                arr[right] = arr[left]                             # 并将其移动到right处

            arr[left] = pivot           # pivot放置到中间left=right处
            return left

        def quickSort(arr, low, high):
            if low >= high:             # 递归结束
                return  
            mid = partition(arr, low, high)     # 以mid为分割点,右边元素>左边元素
            quickSort(arr, low, mid-1)          # 递归对mid两侧元素进行排序
            quickSort(arr, mid+1, high)

        quickSort(nums, 0, len(nums)-1)         # 调用快排函数对nums进行排序
        return nums
gitbingsun commented 2 years ago

class Solution { public: vector sortArray(vector& nums) { int numsCount[50002]= { 0 }; vector ret; for(auto i : nums) { if (i < 0) { numsCount[abs(i)]++; } }

   for(int i = 50001; i > 0; i--) {
       if (numsCount[i] > 0) {
           for(int j = 0; j < numsCount[i]; j++) {
               ret.push_back(-i);
           }
           numsCount[i] = 0;
       }
   }
   cout<<numsCount[2]<<endl;
   for(auto i : nums) {
       if (i >= 0) {
           numsCount[i]++;
       }
   }
   for(int i = 0; i < 50002; i++) {
       if (numsCount[i] > 0) {
           for(int j = 0; j < numsCount[i]; j++) {
               ret.push_back(i);
           }
       }
   }   
   return ret;

} };

ghost commented 2 years ago
class Solution:
    def sortArray(self, nums: List[int]) -> List[int]:
        count_arr = [0] * (50000*2 + 1)
        res = []

        for num in nums:
            count_arr[num+50000] += 1

        for i in range(len(count_arr)):
            if count_arr[i] > 0:
                for _ in range(count_arr[i]):
                    res.append(i-50000)

        return res
maybetoffee commented 2 years ago
class Solution {
    //merge sort
    public int[] sortArray(int[] nums) {
        int[] temp = new int[nums.length];
        mergeSort(nums, 0, nums.length-1, temp);
        return nums;
    }

    private void mergeSort(int[] nums, int start, int end, int[] temp){
        if(start >= end){
            return;
        }

        int mid = (start + end)/2;
        mergeSort(nums, start, mid, temp);
        mergeSort(nums, mid+1, end, temp);

        merge(nums, start, end, temp);
    }

    private void merge(int[] nums, int start, int end, int[] temp){
        int mid = (start + end)/2;
        int left = start, right = mid+1;
        int i = left;

        while(left <= mid && right <=end){
            if(nums[left] <= nums[right]){
                temp[i++] = nums[left++];
            }else{
                temp[i++] = nums[right++];
            }
        }

        while(left <= mid){//now right part is already in temp
            temp[i++] = nums[left++];
        }
        while(right <= end){//now left part is already in temp
            temp[i++] = nums[right++];
        }

        for(int index = start; index<= end; index++){
            nums[index] = temp[index];
        }
    }
}
ZacheryCao commented 2 years ago

Idea

Count Sort

Code

class Solution:
    def sortArray(self, nums: List[int]) -> List[int]:
        count = collections.Counter(nums)
        ans=[]
        for i in range(-5 * 10**4, 5 * 10**4+1):
            if i in count:
                ans+=[i]*count[i]
        return ans

Complexity:

Time: O(5 * 10**4) Space: O(M). M: the count of unique numbers in array

PFyyh commented 2 years ago

题目地址(912. 排序数组)

https://leetcode-cn.com/problems/sort-an-array/

题目描述

给你一个整数数组 nums,请你将该数组升序排列。

 

示例 1:

输入:nums = [5,2,3,1]
输出:[1,2,3,5]

示例 2:

输入:nums = [5,1,1,2,0,0]
输出:[0,0,1,1,2,5]

 

提示:

1 <= nums.length <= 5 * 104
-5 * 104 <= nums[i] <= 5 * 104

前置知识

公司

思路

关键点

代码

Java Code:


class Solution {
    public int[] sortArray(int[] nums) {
        if(nums==null||nums.length<2){
            return nums;
        }
        quickSort(nums,0,nums.length-1);
        return nums;
    }
    private void quickSort(int[] nums,int start,int end){
        if(nums.length<1||start<0||end>nums.length||start>end){
            return;
        }
        if(start<end){
            int left = start;
            int right = end;
            int pivot = nums[start];

            while(left<right){
                //从右边开始,如果循环结束且left<right,表示右边小于基准值
                while(left<right&&nums[right]>=pivot){
                    right--;
                }
                //右移左指针
                if(left<right){
                    nums[left++]=nums[right];
                }
                //从左边继续移动
                while(left<right&&nums[left]<=pivot){
                    left++;
                }
                //把大于基准值扔到右边去
                if(left<right){
                    nums[right--]=nums[left];
                }
            }
            if(left==right){
                nums[left]=pivot;        
            }
            quickSort(nums,start,left-1);
            quickSort(nums,left+1,end);
        }
    }
}

复杂度分析

令 n 为数组长度。

HuiWang1020 commented 2 years ago

Idea

Quick sort

Code

class Solution {
    public int[] sortArray(int[] nums) {
        quick(nums, 0, nums.length - 1);
        return nums;
    }

    public void quick(int[] nums, int left, int right) {
        if (left >= right) return;
        int pivot = partition(nums, left, right);
        quick(nums, left, pivot - 1);
        quick(nums, pivot + 1, right);
}

    public int partition(int[] nums, int left, int right) {
        int p = (right - left) / 2 + left;
        swap(nums, p, right);
        int i = left, j = left;
        while (j < right) {
            if(nums[j] <= nums[right]) {
                swap(nums, i, j);
                i++;
            } 
            j++;
        }
        swap(nums, i, right);
        return i;
    }
    public void swap(int[] nums, int i, int j) {
        int tmp = nums[i];
        nums[i] = nums[j];
        nums[j] = tmp;
    }
}

Complexity

time=O(nlogn) space=O(logn)

MoonLee001 commented 2 years ago

思路

快排

代码

var sortArray = function(nums) {
  const n = nums.length;
  if (n <= 1) {
      return nums;
  }
  const mid = Math.floor(n / 2);
  let pivot = nums.splice(mid, 1)[0];
  let lArr = [], rArr = [];
  for (let i = 0; i < n - 1; i++) {
      if (nums[i] > pivot) {
          rArr.push(nums[i]);
      } else {
          lArr.push(nums[i]);
      }
  }
  return sortArray(lArr).concat([pivot], sortArray(rArr));
}

复杂度分析

KWDFW commented 2 years ago

Day36

912、排序数组

javascript #排序

思路

1、采用快速排序的方式

2、选择数组中的中间位置作为枢

3、枢左侧放入left,右侧放入right

4、left和right再递归调用

5、返回left+枢+right

代码

var sortArray = function(nums) {
  if(nums.length<2) return nums
  const pivotIndex=Math.floor(nums.length/2)
  const pivot=nums.splice(pivotIndex,1)[0]
  //该语句是既取出中间元素又删掉原数组的中间元素
  //splice返回一个长度为1数组,取该数组的首位
  let left=[]
  let right=[]
  for(let n of nums){
    if(n<pivot){
      left.push(n)
    }
    else{
      right.push(n)
    }
  }
  return sortArray(left).concat(pivot,sortArray(right))
};

复杂度分析

时间复杂度:O(nlogn)

空间复杂度:O(logn)

xingchen77 commented 2 years ago

思路

计数排序

代码

    def sortArray(self, nums: List[int]) -> List[int]:
        count_temp = collections.Counter(nums)
        res = []
        for i in range(-5 * 10**4, 5 * 10**4 + 1):
            if i in count_temp:
                res += [i] * count_temp[i]
        return res 

复杂度

时间 O(10**5) \ 空间 O(n)

ShawYuan97 commented 2 years ago

思路

使用快速排序

关键点

代码

Python3 Code:


class Solution:
    def sortArray(self, nums: List[int]) -> List[int]:
        """
        升序数组
        """
        # 使用快排
        self.QuickSort(nums,0,len(nums)-1)
        return nums

    def QuickSort(self,nums,l,r):
        if l >= r:
            return 
        i = self.partition(nums,l,r)
        self.QuickSort(nums,l,i-1)
        self.QuickSort(nums,i+1,r)

    def partition(self,nums,l,r):
        # 最好不要选择第一个元素 否则遇到顺序的数组 时间复杂度退化到O(n^2) 
        pivot_idx = random.randint(l,r)
        nums[l],nums[pivot_idx] = nums[pivot_idx],nums[l]
        pivot = nums[l]
        i,j = l,r
        while i < j:
            # 移动右指针
            while i < j and nums[j] >= pivot:
                j -= 1
            nums[i] = nums[j]
            # 移动左指针
            while i < j and nums[i] <= pivot:
                i += 1
            nums[j] = nums[i]
        nums[i] = pivot
        return i
wychmod commented 2 years ago

思路

归并排序

代码

class Solution(object):
    def sortArray(self, nums):
        """
        :type nums: List[int]
        :rtype: List[int]
        """
        self.merge_sort(nums, 0, len(nums)-1)
        return nums

    def merge_sort(self, arr, L, R):
        if L == R:
            return
        mid = L + (R-L)//2
        self.merge_sort(arr, L, mid)
        self.merge_sort(arr, mid+1, R)
        self.merge(arr, L, mid, R)

    def merge(self, arr, L, mid, R):
        tmp = []
        p1, p2 = L, mid+1
        while p1 <= mid and p2 <= R:
            if arr[p1] <= arr[p2]:
                tmp.append(arr[p1])
                p1 += 1
            else:
                tmp.append(arr[p2])
                p2 += 1
        while p1 <= mid:
            tmp.append(arr[p1])
            p1 += 1
        while p2 <= R:
            tmp.append(arr[p2])
            p2 += 1
        arr[L:R+1] = tmp

复杂度

时间复杂度Onlogn 空间复杂度On

houmk1212 commented 2 years ago

思路

手写归并排序

代码

class Solution {
   public int[] sortArray(int[] nums) {
        int[] tmp = new int[nums.length];
        sort(nums, 0, nums.length - 1, tmp);
        return nums;
    }

    private void sort(int[] nums, int a, int b, int[] tmp) {
        if (a == b)
            return;

        int mid = a + (b - a) / 2;
        sort(nums, a, mid, tmp);
        sort(nums, mid + 1, b, tmp);

        int l = a;
        int r = mid + 1;
        int index = a;
        while (l <= mid && r <= b) {
            if (nums[l] < nums[r]) {
                tmp[index++] = nums[l++];
            } else {
                tmp[index++] = nums[r++];
            }
        }
        while (l <= mid) {
            tmp[index++] = nums[l++];
        }
        while (r <= b) {
            tmp[index++] = nums[r++];
        }
        for (int i = a; i <= b; i++) {
            nums[i] = tmp[i];
        }
    }
}

复杂度

dzwhh commented 2 years ago

【Day 36】912. Sort an Array「排序数组」

题目描述

给你一个整数数组 nums,请你将该数组升序排列。

示例 1

输入:nums = [5,2,3,1] 输出:[1,2,3,5]

前置知识

思路

快速排序,通过每次选取pivot点,小于pivot放左边,大于pivot放右边,递归下去,最后左右合并,通过拆分和合并的方式实现有序

代码

var sortArray = function(nums) {
  const arr = [...nums];
  if(arr.length < 2) return arr;
  const pivotIndex = Math.floor(arr.length / 2);
  const pivot = arr[pivotIndex];
  const [lo,hi] = arr.reduce(
    (acc, val, i) => {
      if(val < pivot || (val === pivot && i != pivotIndex)){
        acc[0].push(val)
      }else if (val > pivot){
        acc[1].push(val)
      }
      return acc;
    } 
  ,[[],[]])
  return [...sortArray(lo),pivot,...sortArray(hi)];
}; 

复杂度分析

时间复杂度:O(nlogn) 空间复杂度:O(n)

liuguang520-lab commented 2 years ago

思路

使用堆进行排序

code

class Solution {
public:
    vector<int> sortArray(vector<int>& nums) {
        int n = nums.size();
        priority_queue<int,vector<int>,greater<int>> q;

        for(int i = 0; i< n; i++)
        {
            q.push(nums[i]);
        }
        for(int i = 0; i<n;i++)
        {
            nums[i] = q.top();
            q.pop();
        }
        return nums;
    }
};

复杂度分析

MichaelXi3 commented 2 years ago

Idea

nancychien commented 2 years ago
class Solution:
    def sortArray(self, nums: List[int]) -> List[int]:
        self.mergeSort(nums)
        return nums

    def mergeSort(self, nums): 
        if len(nums) > 1: 
            mid = len(nums)//2
            L = nums[:mid] 
            R = nums[mid:] 

            self.mergeSort(L)
            self.mergeSort(R)

            i = j = k = 0

            while i < len(L) and j < len(R): 
                if L[i] < R[j]: 
                    nums[k] = L[i] 
                    i+=1
                else: 
                    nums[k] = R[j] 
                    j+=1
                k+=1

            while i < len(L): 
                nums[k] = L[i] 
                i+=1
                k+=1

            while j < len(R): 
                nums[k] = R[j] 
                j+=1
                k+=1

Time: O(nlogn) Space: O(n)

Venchyluo commented 2 years ago

merge sort.

class Solution:
    def sortArray(self, nums: List[int]) -> List[int]:        
        if len(nums) <= 1: return nums
        mid = len(nums)//2
        left = self.sortArray(nums[:mid])
        right = self.sortArray(nums[mid:])
        return self.mergeSort(left, right)

    def mergeSort(self,left, right):
        res = []
        i, j = 0, 0
        while i < len(left) and j < len(right):
            if left[i] < right[j]:
                res.append(left[i])
                i += 1
            else:
                res.append(right[j])
                j += 1

        res += left[i:]
        res += right[j:]
        return res

time complexity: O(N longN) space complexity: O(N)

JudyZhou95 commented 2 years ago
"""
class Solution:
    def sortArray(self, nums: List[int]) -> List[int]:
        l = len(nums)
        if l <= 1:
            return nums

        arr1 = self.sortArray(nums[:l//2])
        arr2 = self.sortArray(nums[l//2:])   
        res = self.mergeSortedArray(arr1, arr2)
        return res

    def mergeSortedArray(self, arr1, arr2):
        res = []

        p1, p2 = 0, 0

        while p1 < len(arr1) and p2 < len(arr2):
            if arr1[p1] <= arr2[p2]:
                res.append(arr1[p1])
                p1 += 1
            else:
                res.append(arr2[p2])
                p2 += 1

        if p1 < len(arr1):
            res += arr1[p1:]
        if p2 < len(arr2):
            res += arr2[p2:]

        return res
"""

class Solution:
    def sortArray(self, nums: List[int]) -> List[int]:
        self.quickSort(nums, 0, len(nums)-1)
        return nums

    def quickSort(self, nums, l, r):
        if l >= r:
            return 

        p = self.partition(nums, l, r)
        self.quickSort(nums, l, p-1)
        self.quickSort(nums, p+1, r)

    def partition(self, nums, l, r):
        mid = l + (r-l)//2
        pivot = nums[mid]

        nums[l], nums[mid] = nums[mid], nums[l]

        i = l+1
        j = r

        while i <= j:
            while i <= j and nums[i] <= pivot:
                i += 1
            while i <= j and nums[j] >= pivot:
                j -= 1

            if i < j:
                nums[i], nums[j] = nums[j], nums[i]

        nums[l], nums[j] = nums[j], nums[l]
        return j
zuoduozhongguo commented 2 years ago

code

class Solution:
    def sortArray(self, nums: List[int]) -> List[int]:
        nums.sort()
        return nums
freedom0123 commented 2 years ago
class Solution {
    public int[] sortArray(int[] nums) {      
        Arrays.sort(nums);
        return nums;
    }
}
Jessie725 commented 2 years ago

class Solution { public int[] sortArray(int[] nums) {

    if (nums.length == 0) { return nums;}

    QuickSort(nums, 0, nums.length - 1);
    return nums;

}

private void QuickSort(int[] nums, int start, int end) {

    if(start >= end) return;

    int pivot = nums[(start + end)/2];
    int left = start, right = end;

    while (left <= right) {
        while (left <= right && nums[left] < pivot ) {
        left++;
        }

        while (left <= right && nums[right] > pivot) {
        right--;
        }

        if(left <= right) {
            int temp;
            temp = nums[left];
            nums[left] = nums[right];
            nums[right] = temp;

            left++;
            right--;
        }
    }

   QuickSort(nums, start, right);
   QuickSort(nums, left, end);

}

}

Ellie-Wu05 commented 2 years ago

quick sort

代码

class Solution:
    def quickSort(self, nums):
        def helper(head, tail):
            if head >= tail: return 
            l, r = head, tail
            m = (r - l) // 2 + l
            pivot = nums[m]
            while r >= l:
                while r >= l and nums[l] < pivot: l += 1
                while r >= l and nums[r] > pivot: r -= 1
                if r >= l:
                    nums[l], nums[r] = nums[r], nums[l]
                    l += 1
                    r -= 1
            helper(head, r)
            helper(l, tail)

        helper(0, len(nums)-1)
        return nums

    def sortArray(self, nums: List[int]) -> List[int]:

        self.quickSort(nums)
        return nums
lxgang65 commented 2 years ago

思路

讲义里的冒泡排序

code

class Solution {
    public int[] sortArray(int[] nums) {
        for(int i = 0; i<nums.length-1;i++){
            for(int j = 1; j<nums.length  - i ;j++){
                if(nums[j-1] > nums[j]){
                   int temp = nums[j-1];
                   nums[j-1] = nums[j];
                   nums[j] = temp;
                }
            }
        }
        return nums;
    }
}

复杂度

revisegoal commented 2 years ago

排序算法总结

class Solution {
    public int[] sortArray(int[] nums) {
        // selectionSort(nums);
        // insertionSort(nums, 0, nums.length - 1);
        // shellSort(nums);
        quickSort(nums, 0, nums.length - 1);// 最快
        // mergeSort(nums, 0, nums.length - 1, new int[nums.length]);
        // radixSort(nums); // 报错,因为基数排序不支持排序负数
        //heapSort(nums);
        return nums;
    }

    // 冒泡排序 O(n^2):可通过判断一轮比较后没有进行交换提前跳出来优化
    void bubbleSort(int[] nums) {
        // 比较次数
        for (int i = 0; i < nums.length - 1; i++) {
            // 每次比较需要遍历的下标
            for (int j = 0; j < nums.length - 1 - i; j++) {
                if (nums[j] > nums[j + 1]) {
                    swap(nums, j, j + 1);
                }
            }
        }
    }

    // 选择排序 O(n^2)
    void selectionSort(int[] nums) {
        for (int i = 0; i < nums.length - 1; i++) {
            int minIndex = i;
            int min = nums[i];
            for (int j = i + 1; j < nums.length; j++) {
                if (nums[j] < min) {
                    min = nums[j];
                    minIndex = j;
                }
            }
            swap(nums, i, minIndex);
        }
    }

    // 插入排序 O(n^2)
    void insertionSort(int[] nums, int left, int right) {
        for (int i = left + 1; i <= right; i++) {
            int insertedVal = nums[i];
            int insertedIndex = i - 1;// 待插入数前面数的下标
            while (insertedIndex >= 0 && insertedVal < nums[insertedIndex]) {
                nums[insertedIndex + 1] = nums[insertedIndex];
                insertedIndex--;
            }
            nums[insertedIndex + 1] = insertedVal;
        }
    }

    // 希尔排序 O(nlog^2(n)):增量分组 + 插入排序
    void shellSort(int[] nums) {
        for (int gap = nums.length / 2; gap > 0; gap /= 2) {
            for (int i = gap; i < nums.length; i++) {
                int insertedVal = nums[i];
                int insertedIndex = i - gap;
                while (insertedIndex >= 0 && insertedVal < nums[insertedIndex]) {
                    nums[insertedIndex + gap] = nums[insertedIndex];
                    insertedIndex -= gap;
                }
                nums[insertedIndex + gap] = insertedVal;
            }
        }
    }

    // 快速排序 O(nlog(n)):冒泡排序的改进
    final int INSERTION_SORT_THRESHOLD = 7;
    void quickSort(int[] nums, int left, int right) {
        // 小于一定阈值换用插入排序
        if (right - left <= INSERTION_SORT_THRESHOLD) {
            insertionSort(nums, left, right);
            return;
        }
        int pIndex = partition(nums, left, right);
        quickSort(nums, left, pIndex - 1);
        quickSort(nums, pIndex + 1, right);
    }

    Random random = new Random();
    int partition(int[] nums, int left, int right) {
        int randomIndex = left + random.nextInt(right - left + 1);
        swap(nums, left, randomIndex);
        int pivot = nums[left];
        int lt = left;
        for (int i = left + 1; i <= right; i++) {
            if (nums[i] < pivot) {
                lt++;
                swap(nums, i, lt);
            }
        }
        swap(nums, lt, left);
        return lt;
    }

    // 归并排序 O(nlog(n))
    void mergeSort(int[] nums, int left, int right, int[] tmp) {
        if (left >= right) {
            return;
        }
        int mid = left + (right - left) / 2;
        mergeSort(nums, left, mid, tmp);
        mergeSort(nums, mid + 1, right, tmp);
        merge(nums, left, right, tmp);
    }

    void merge(int[] nums, int left, int right, int[] tmp) {
        // 1. 合并到临时数组
        int mid = left + (right - left) / 2;
        int i = left, j = mid + 1, t = 0;
        while (i <= mid && j <= right) {
            if (nums[i] <= nums[j]) {
                tmp[t++] = nums[i++]; 
            } else {
                tmp[t++] = nums[j++];
            }
        }
        while (i <= mid) {
            tmp[t++] = nums[i++];
        }
        while (j <= right) {
            tmp[t++] = nums[j++];
        }
        // 2. 复制回原数组
        t = 0;
        i = left; 
        while (i <= right) {
            nums[i++] = tmp[t++];
        }
    }

    // 基数排序 O(n * bucketSum):空间换时间的经典算法,不支持排序负数
    void radixSort(int[] nums) {
        final int RADIX = 10;
        int[][] bucket = new int[RADIX][nums.length];
        int[] bucketElementCount = new int[RADIX];
        int max = nums[0];
        for (int i = 0; i < nums.length; i++) {
            max = Math.max(max, nums[i]);
        }
        int maxDigit = ("" + max).length();
        for (int i = 0, digit = 1; i < maxDigit; i++, digit *= 10) {
            for (int j = 0; j < nums.length; j++) {
                int digitElement = nums[j] / digit % 10;
                bucket[digitElement][bucketElementCount[digitElement]] = nums[j];
                bucketElementCount[digitElement]++;
            }
            int index = 0;
            for (int k = 0; k < RADIX; k++) {
                for (int l = 0; l < bucketElementCount[k]; l++) {
                    nums[index++] = bucket[k][l];
                }
                bucketElementCount[k] = 0;
            }
        }
    }

    // 堆排序 O(nlog(n))
    void heapSort(int[] nums) {
        for (int i = nums.length / 2 - 1; i >= 0; i--) {
            adjustHeap(nums, nums.length, i);
        }
        for (int i = nums.length - 1; i >= 0; i--) {
            swap(nums, i, 0);
            adjustHeap(nums, i, 0);
        }
    }

    void adjustHeap(int[] nums, int len, int nodeIndex) {
        int tmp = nums[nodeIndex];
        for (int i = 2 * nodeIndex + 1; i < len; i = 2 * i + 1) {
            if (i + 1 < len && nums[i + 1] > nums[i]) {
                i++;
            }
            if (nums[i] > tmp) {
                nums[nodeIndex] = nums[i];
                nodeIndex = i;
            } else {
                break;
            }
        }
        nums[nodeIndex] = tmp;
    } 

    void swap(int[] nums, int a, int b) {
        int tmp = nums[a];
        nums[a] = nums[b];
        nums[b] = tmp;
    }
}
physicshi commented 2 years ago

思路

归并排序

代码

impl Solution {
    pub fn sort_array(nums: Vec<i32>) -> Vec<i32> {
        Self::merge_sort(&nums)
    }

    fn merge_sort(src: &[i32]) -> Vec<i32> {
        if src.len() <= 1 {
            return src.to_vec();
        }

        let mid = src.len() / 2;
        let pt1 = Self::merge_sort(&src[..mid]);
        let pt2 = Self::merge_sort(&src[mid..src.len()]);
        let mut res = vec![];
        let mut i = 0;
        let mut j = 0;
        while i < pt1.len() || j < pt2.len() {
            if i < pt1.len() && j < pt2.len() {
                if pt1[i] < pt2[j] {
                    res.push(pt1[i]);
                    i += 1;
                } else {
                    res.push(pt2[j]);
                    j += 1;
                }
            } else if i < pt1.len() {
                res.push(pt1[i]);
                i += 1;
            } else if j < pt2.len() {
                res.push(pt2[j]);
                j += 1;
            }
        }
        res
    }
}

复杂度

hyh331 commented 2 years ago

Day36 思路

本题思路采用归并排序算法,此题需掌握,快速排序,归并排序,堆排序

class Solution {
    //具体实现细节
    void merge(vector<int>& nums,int left,int right,vector<int>& ans)
    {
        int mid=(right-left)/2+left;
        int i=left,j=mid+1,k=0;
        //情况1
        while(i<=mid&&j<=right)
        {
            //注意写成 < 就丢失了稳定性(相同元素原来靠前的排序以后依然靠前)
            if(nums[i]<=nums[j]){
                //可以写成ans[k++]=nums[i++]
                ans[k]=nums[i];
                i++;
                k++;
            }
            else {
                ans[k]=nums[j];
                j++;
                k++;
            }
        }
        //情况2
        while(i<=mid)
        {
            ans[k]=nums[i];
            i++;
            k++;
        }
        //情况3
        while(j<=right){
            ans[k]=nums[j];
            j++;
            k++;
        }
        //将临时数组tmp的数组复制到nums中,为什么是i-left?????
        for(int i=left;i<=right;i++)
            nums[i]=ans[i-left];
    }
    //递归
    void mergeSort(vector<int>& nums,int left,int right,vector<int>& ans)
    {
        //递归结束标志
        if(left>=right)
            return ;
        //设置中间值,这样写是为了保证数据过大时不溢出
        int mid=(right-left)/2+left;
        //递归地将数组分为一个个有序序列
        mergeSort(nums,left,mid,ans);
        mergeSort(nums,mid+1,right,ans);
        //再次调用递归将两部分有序数组合二为一
        merge(nums,left,right,ans);
    }
public:
    vector<int> sortArray(vector<int>& nums) {
        vector <int> ans(nums.size());
        mergeSort(nums,0,nums.size()-1,ans);
        return nums;
    }
};

复杂度分析

biscuit279 commented 2 years ago

思路:

快速排序 import random class Solution(object): def randomized_partition(self, nums, l, r): pivot = random.randint(l, r) nums[pivot], nums[r] = nums[r], nums[pivot] i = l - 1 for j in range(l, r): if nums[j] < nums[r]: i += 1 nums[i], nums[j] = nums[j], nums[i] i += 1 nums[i], nums[r] = nums[r], nums[i] return i

def randomized_quicksort(self, nums, l, r):
    if r - l <= 0:
        return
    mid = self.randomized_partition(nums, l, r)
    self.randomized_quicksort(nums, l, mid - 1)
    self.randomized_quicksort(nums, mid + 1, r)

def sortArray(self, nums):
    self.randomized_quicksort(nums, 0, len(nums) - 1)
    return nums

时间复杂度:O(nlogn)

空间复杂度:O(logn)

577961141 commented 2 years ago

912. 排序数组

时间

题目链接

https://leetcode-cn.com/problems/sort-an-array/

题目思路

解法一:快速排序

解法二:计数排序(不写)

题目的题解code

解法一:

<?php
class Solution {

    /**
     * @param Integer[] $nums
     * @return Integer[]
     */
    function sortArray($nums) {
        if (count($nums) < 2) {
            return $nums;
        }

        $middle = $nums[0];
        $leftArray = [];
        $rightArray = [];

        for ($i = 1; $i < count($nums); $i++) {
            if ($middle > $nums[$i]) {
                $leftArray[] = $nums[$i];
            } else {
                $rightArray[] = $nums[$i];
            }
        }
        $leftArray = $this->sortArray($leftArray);
        $leftArray[] = $middle;
        $rightArray = $this->sortArray($rightArray);

        return array_merge($leftArray, $rightArray);
    }
}
func sortArray(nums []int) []int {
    return _quickSort(nums, 0, len(nums) -1)
}

func _quickSort(arr []int, left, right int) []int{
    if left < right {
        index := partition(arr, left, right)
        _quickSort(arr, left, index-1)
        _quickSort(arr, index+1, right)
    }
    return arr
}

func partition(arr []int, left, right int) int {
    pivot := left;
    index := pivot+1

    for i := index; i <= right; i++ {
        if arr[pivot] > arr[i] {
            swap(arr, i, index)
            index += 1
        }
    }

    swap(arr, pivot, index -1)
    return index -1
}

func swap(arr []int, i, j int) {
    arr[i], arr[j] = arr[j], arr[i]
}

时间和空间复杂度

时间复杂度:O(nlogn) 空间复杂度:O(logn)

JiangWenqi commented 2 years ago
class Solution {
public:
    vector<int> sortArray(vector<int>& nums) {
        sort(nums.begin(), nums.end());
        return nums;
    }
};
L-SUI commented 2 years ago

/**
 * @param {number[]} nums
 * @return {number[]}
 */
var sortArray = function(nums) {
    if( nums.length <= 1 ) return nums
    let left = []
    let right = []
    let pivotIndex  = Math.floor(nums.length / 2)
    let pivotValue =  nums.splice(pivotIndex,1)[0]
    for(let i = 0; i < nums.length; i++ ){
        if(nums[i] > pivotValue){
            right.push(nums[i])
        }else{
            left.push(nums[i])
        }
    }
    return sortArray(left).concat(pivotValue,sortArray(right))
};
JasonHe-WQ commented 2 years ago

我只会调用,是个傻逼

class Solution:
    def sortArray(self, nums: List[int]) -> List[int]:
        nums.sort()
        return nums
miss1 commented 2 years ago

思路

归并排序

代码

var sortArray = function(nums) {
  if (nums.length === 1) return nums;
  return mergeSort(nums, 0, nums.length - 1);
};

const mergeSort = function(nums, start, end) {
  if (start >= end) return [nums[start]];
  let mid = start + ((end - start) >> 1);
  let left = mergeSort(nums, start, mid);
  let right = mergeSort(nums, mid + 1, end);
  return sortOrderlyArray(left, right);
};

const sortOrderlyArray = function(a, b) {
  let i = 0, j = 0;
  let res = [];
  while (i < a.length || j < b.length) {
    if (i >= a.length || a[i] > b[j]) {
      res.push(b[j]);
      j++;
      continue;
    }
    if (j >= b.length || a[i] <= b[j]) {
      res.push(a[i]);
      i++;
    }
  }
  return res;
};

复杂度

time: O(nlogn)

space: O(n)

zhishinaigai commented 2 years ago

思路

归并

代码

class Solution {
public:
    vector<int> tmp;
    void mergesort(vector<int>& nums,int l,int r){
        if(l>=r) return;
        int mid=(l+r)>>1;
        mergesort(nums,l,mid);
        mergesort(nums,mid+1,r);
        int i=l,j=mid+1;
        int cnt=0;
        while(i<=mid&&j<=r){
            if(nums[i]<=nums[j]) tmp[cnt++]=nums[i++];
            else tmp[cnt++]=nums[j++];
        }
        while(i<=mid){
            tmp[cnt++]=nums[i++];
        }
        while(j<=r){
            tmp[cnt++]=nums[j++];
        }
        for(int i=0;i<r-l+1;i++){
            nums[i+l]=tmp[i];
        }
    }
    vector<int> sortArray(vector<int>& nums) {
        tmp.resize((int)nums.size(),0);
        mergesort(nums,0,(int)nums.size()-1);
        return nums;
    }
};
Orangejuz commented 2 years ago

思路:

快排

代码

class Solution:
    def sortArray(self, nums: List[int]) -> List[int]:
        def quicksort(nums,left,right):
            flag=nums[(left+right)//2]              
            i,j=left,right                         
            while i<=j:
                while nums[i]<flag: i+=1            
                while nums[j]>flag: j-=1            
                if i<=j:
                    nums[i],nums[j]=nums[j],nums[i] 
                    i+=1                            
                    j-=1                           
            if i<right: quicksort(nums,i,right)     
            if j>left:  quicksort(nums,left,j)      
        quicksort(nums,0,len(nums)-1)               
        return nums                                 
oneline-wsq commented 2 years ago

思路:快速排序

代码

class Solution:
    def sortArray(self, nums: List[int]) -> List[int]:
        def partition(arr,low,high):
            pivot_idx=random.randint(low,high)              # 随机选择pivot
            arr[low],arr[pivot_idx]=arr[pivot_idx],arr[low] # pivot放置到最左边
            pivot=arr[low]

            left,right=low,high
            while left<right:
                while left<right and arr[right]>=pivot: # 找到右边第一个<pivot的元素
                    right-=1
                arr[left]=arr[right]

                while left<right and arr[left]<=pivot:
                    # 找到左边第一个>pivot的元素
                    left+=1
                arr[right]=arr[left]

            arr[left]=pivot # pivot放置到中间left=right处
            return left
        def quickSort(arr,low,high):
            if low>high:
                return 
            mid=partition(arr,low,high) # 以mid为分割点,右边元素>左边元素
            quickSort(arr,low,mid-1)
            quickSort(arr,mid+1,high)

        quickSort(nums,0,len(nums)-1)
        return nums

复杂度分析

时间复杂度:O(nlogn)

空间复杂度:O(logn)

zhulin1110 commented 2 years ago

题目地址(912. 排序数组)

https://leetcode-cn.com/problems/sort-an-array/

题目描述

给你一个整数数组 nums,请你将该数组升序排列。

 

示例 1:

输入:nums = [5,2,3,1]
输出:[1,2,3,5]

示例 2:

输入:nums = [5,1,1,2,0,0]
输出:[0,0,1,1,2,5]

 

提示:

1 <= nums.length <= 5 * 104
-5 * 104 <= nums[i] <= 5 * 104

思路

JavaScript Code:


/**
 * @param {number[]} nums
 * @return {number[]}
 */
var sortArray = function(nums) {
   if (nums.length <= 1) { return nums; }
    var pivotIndex = Math.floor(nums.length / 2);
    var pivot = nums.splice(pivotIndex, 1)[0]; 
    var left = [];
    var right = [];
    for (var i = 0; i < nums.length; i++){
        if (nums[i] < pivot) {
            left.push(nums[i]);
        } else {
            right.push(nums[i]);
        }
    }
    return sortArray(left).concat([pivot], sortArray(right));
};

复杂度分析

令 n 为数组长度。

LQyt2012 commented 2 years ago

思路

快速排序

代码

class Solution:
    def sortArray(self, nums: List[int]) -> List[int]:
        self.quickSort(nums, 0, len(nums)-1)
        return nums

    def partition(self, arr, low, high):
        pivot_idx = random.randint(low, high)
        arr[low], arr[pivot_idx] = arr[pivot_idx], arr[low]
        pivot = arr[low]

        left, right = low, high
        while left < right:
            while left < right and arr[right] >= pivot:
                right -= 1
            arr[left] = arr[right]

            while left < right and arr[left] <= pivot:
                left += 1
            arr[right] = arr[left]
        arr[left] = pivot
        return left

    def quickSort(self, arr, low, high):
        if low >= high:
            return

        mid = self.partition(arr, low, high)
        self.quickSort(arr, low, mid-1)
        self.quickSort(arr, mid+1, high)
func partition(nums []int, low, high int) int {
    rand.Seed(time.Now().UnixNano())

    pivotIdx := rand.Intn(high-low) + low
    nums[low], nums[pivotIdx] = nums[pivotIdx], nums[low]
    pivot := nums[low]

    left, right := low, high
    for left < right {

        for left < right && nums[right] >= pivot {
            right--
        }
        nums[left] = nums[right]
        for left < right && nums[left] <= pivot {
            left++
        }
        nums[right] = nums[left]
    }
    nums[left] = pivot
    return left
}

func quickSort(nums []int, low, high int) {
    if low >= high {
        return
    }
    mid := partition(nums, low, high)
    quickSort(nums, low, mid-1)
    quickSort(nums, mid+1, high)
}

复杂度分析

时间复杂度:O(NlogN)
空间复杂度:O(logN)

mo660 commented 2 years ago

思路

快速排序

代码

class Solution {
public:
    void swap(vector<int>& nums, int i, int j){
        int tmp = nums[i];
        nums[i] = nums[j];
        nums[j] = tmp;
    }
    void fastSort(vector<int>& nums, int start, int end){
        if (start >= end) return;
        int pivot = nums[start + ((end - start)/2)];
        int l = start;
        int r = end;
        while(l <= r){
            while(nums[l] < pivot)l++;
            while(nums[r] > pivot)r--;
            if(l <= r){
                swap(nums,l,r);
                l++;
                r--;
            }
        }
        fastSort(nums,start,r);
        fastSort(nums,l,end);
    }
    vector<int> sortArray(vector<int>& nums) {
        fastSort(nums, 0, nums.size()-1);
        return nums;
    }
};
XXjo commented 2 years ago

思路

快速排序

代码

var quickSort = function(arr, start, end){
    if(start >= end) return;
    let left = start;
    let right = end;
    let pivot = arr[left];
    while(left < right){
        //顺序很重要,要先从右边开始找,因为pivot是arr[left],从右边开始找可以保证数据不丢失
        while((left < right) && arr[right] >= pivot) right--;
        if(arr[right] < pivot){
            arr[left] = arr[right];
        }
        //再找左边
        while((left < right) && arr[left] <= pivot) left++;
        if(arr[left] > pivot){
            arr[right] = arr[left];
        }
    }
    arr[left] = pivot;
    quickSort(arr, start, left - 1);
    quickSort(arr, left + 1, end);

}

var sortArray3 = function(nums) {
    quickSort(nums, 0, nums.length - 1);
    return nums;
};

复杂度分析

时间复杂度:O(nlgn)
空间复杂度:O(nlgn)

xil324 commented 2 years ago
class Solution(object):
    def sortArray(self, nums):
        """
        :type nums: List[int]
        :rtype: List[int]
        """
        self.quick_sort (0, len(nums)-1, nums);
        return nums; 

    def quick_sort(self, start, end, arr):
        if start >= end:
            return; 
        pos = self.partition(start, end, arr); 
        self.quick_sort(start, pos-1, arr); 
        self.quick_sort(pos+1,end, arr); 

    def partition(self,start, end, arr): 
        index = start; 
        ran = randint(start,end); 
        self.swap(ran, end, arr); 
        pivot = arr[end]; 
        for i in range(start,end):
            if arr[i] < pivot:
                self.swap(index, i,arr); 
                index +=1; 
        self.swap(index, end, arr);    
        return index; 

    def swap(self, left, right, arr):
        arr[left], arr[right] = arr[right], arr[left]
        return arr; 

时间复杂度:o(nlogn)

taojin1992 commented 2 years ago
/*
quick sort:
O(n^2) time when it is reversed

the best case:
    [half] pivot [half]

    T(n) = O(n) + 2*T(n/2)
    O(nlogn)

    avg case:
    O(nlogn)

    Space: 
    avg: O(logn)
    worst: O(n)

    The average case space used will be of the order O(log n) .
    The worst case space complexity becomes O(n) , 
    when the algorithm encounters its worst case where for 
    getting a sorted list, we need to make n recursive calls.

*/

class Solution {
    public int[] sortArray(int[] nums) {
        shuffle(nums);
        quickSort(nums, 0, nums.length - 1);
        return nums;
    }

    // O(n) time
    private void shuffle(int[] nums) {
        Random rand = new Random();

        for (int i = 0; i < nums.length; i++) {
            int randomIndexToSwap = rand.nextInt(nums.length);
            swap(nums, i, randomIndexToSwap);
        }

    }

    private void quickSort(int[] nums, int start, int end) {
        if (start >= end) {
            return;
        }
        int pivotIndex = start, left = start + 1, right = end;
        while (left <= right) {
            if (nums[left] > nums[pivotIndex] && nums[right] <= nums[pivotIndex]) {
                swap(nums, left, right);
            }
            if (nums[left] <= nums[pivotIndex]) {
                left++;
            }
            if (nums[right] > nums[pivotIndex]) {
                right--;
            }
        }
        swap(nums, pivotIndex, right);
        if (right - 1 - start + 1 >= end - right - 1 + 1) {
            quickSort(nums, right + 1, end);
            quickSort(nums, start, right - 1);
        } else {
            quickSort(nums, start, right - 1);
            quickSort(nums, right + 1, end);
        }

    }
    private void swap(int[] nums, int i, int j) {
        int temp = nums[i];
        nums[i] = nums[j];
        nums[j] = temp;
    }
}
kite-fly6618 commented 2 years ago

思路:

归并排序

代码:

var sortArray = function(nums) {
  return splitList(nums)
};
// 拆分数组
function splitList (list) {
  let len = list.length
  if(len === 1) return list
  let mid = len >> 1
  let left = list.slice(0, mid)
  let right = list.slice(mid)
  return mergeList(splitList(left), splitList(right))
}
// 合并, 排序数组
function mergeList (left, right) {
  let res = []
  let il = 0, lenl = left.length
  let ir = 0, lenr = right.length
  while(il < lenl && ir < lenr){
    if(left[il] < right[ir]){
      res.push(left[il++])
    } else {
      res.push(right[ir++])
    }
  }
  while(il < lenl){
    res.push(left[il++])
  }
  while(ir < lenr){
    res.push(right[ir++])
  }
  return res
}

复杂度:

时间复杂度: O(nlogn)
空间复杂度: O(n)

weihaoxie commented 2 years ago

思路

zenwangzy commented 2 years ago

class Solution {
public:
    vector<int> sortArray(vector<int>& nums) {
        sort(nums.begin(), nums.end());
        return nums;
    }
};
flaming-cl commented 2 years ago
function sortArray(arr, left, right) {
    var len = arr.length,
        partitionIndex,
        left = typeof left != 'number' ? 0 : left,
        right = typeof right != 'number' ? len - 1 : right;

    if (left < right) {
        partitionIndex = partition(arr, left, right);
        sortArray(arr, left, partitionIndex-1);
        sortArray(arr, partitionIndex+1, right);
    }
    return arr;
}

function partition(arr, left ,right) {     // 分区操作
    var pivot = left,                      // 设定基准值(pivot)
        index = pivot + 1;
    for (var i = index; i <= right; i++) {
        if (arr[i] < arr[pivot]) {
            swap(arr, i, index);
            index++;
        }        
    }
    swap(arr, pivot, index - 1);
    return index-1;
}

function swap(arr, i, j) {
    var temp = arr[i];
    arr[i] = arr[j];
    arr[j] = temp;
}
flyzenr commented 2 years ago
linjunhe commented 2 years ago
class Solution:
    def sortArray(self, nums: List[int]) -> List[int]:

        def partition(arr, low, high):
            pivot_idx = random.randint(low, high)                   # 随机选择pivot
            arr[low], arr[pivot_idx] = arr[pivot_idx], arr[low]     # pivot放置到最左边
            pivot = arr[low]                                        # 选取最左边为pivot

            left, right = low, high     # 双指针
            while left < right:

                while left<right and arr[right] >= pivot:          # 找到右边第一个<pivot的元素
                    right -= 1
                arr[left] = arr[right]                             # 并将其移动到left处

                while left<right and arr[left] <= pivot:           # 找到左边第一个>pivot的元素
                    left += 1
                arr[right] = arr[left]                             # 并将其移动到right处

            arr[left] = pivot           # pivot放置到中间left=right处
            return left

        def quickSort(arr, low, high):
            if low >= high:             # 递归结束
                return  
            mid = partition(arr, low, high)     # 以mid为分割点,右边元素>左边元素
            quickSort(arr, low, mid-1)          # 递归对mid两侧元素进行排序
            quickSort(arr, mid+1, high)

        quickSort(nums, 0, len(nums)-1)         # 调用快排函数对nums进行排序
        return nums
AConcert commented 2 years ago
function sortArray(nums: number[]): number[] {
    for (let i = 0; i < nums.length - 1; i++) {

        let minIndex = i;

        for (let j = i; j < nums.length - 1; j++) {

            if (nums[minIndex] > nums[j + 1]) {
                minIndex = j + 1;
            }
        }

        if (minIndex !== i) {
            const temp = nums[i];
            nums[i] = nums[minIndex];
            nums[minIndex] = temp;
        }
    }
    return nums;
};
ShuqianYang commented 2 years ago

代码

Python3 Code:


class Solution:
    def randomized_partition(self, nums, l, r):
        pivot = random.randint(l, r)
        nums[pivot], nums[r] = nums[r], nums[pivot]
        i = l - 1
        for j in range(l, r):
            if nums[j] < nums[r]:
                i += 1
                nums[j], nums[i] = nums[i], nums[j]
        i += 1
        nums[i], nums[r] = nums[r], nums[i]
        return i

    def randomized_quicksort(self, nums, l, r):
        if r - l <= 0:
            return
        mid = self.randomized_partition(nums, l, r)
        self.randomized_quicksort(nums, l, mid - 1)
        self.randomized_quicksort(nums, mid + 1, r)

    def sortArray(self, nums: List[int]) -> List[int]:
        self.randomized_quicksort(nums, 0, len(nums) - 1)
        return nums

复杂度分析

令 n 为数组长度。