排序

排序是实际运用中比较常见的情况。计算机界也对排序进行了很深入的研究。常见的排序算法有:快速排序、归并排序、插入排序、堆排序等等。
在一些算法题目当中,排序经常是作为一个实现的前提条件。比如求解 Kth Element 问题或者 TopK Elements 问题。
LeedCode中就有一些题目是需要采用排序解决或者解决排序问题。
1、找到第K大元素
215. Kth Largest Element in an Array (Medium)
题目可以采用各种方法:如各种排序算法、K个元素的堆排序等。。

/*采用go语言自带的排序算法(快排)后直接返回倒数第K个元素*/
func findKthLargest(nums []int, k int) int {
    sort.Sort(sort.IntSlice(nums))
    length := len(nums)
    return nums[length-k] 
}
/*Java的优先级序列来作为堆实现*/
public int findKthLargest(int[] nums, int k) {
    PriorityQueue<Integer> pq = new PriorityQueue<>(); // 小顶堆
    for (int val : nums) {
        pq.add(val);
        if (pq.size() > k)  // 维护堆的大小为 K
            pq.poll();
    }
    return pq.peek();
}

2、桶排序
如题目1:出现频率最多的 k 个数
347. Top K Frequent Elements (Medium)

Given [1,1,1,2,2,3] and k = 2, return [1,2].
//利用桶排序。
func topKFrequent(nums []int, k int) []int {
    //1、先统计各个数字出现的次数
    var m = make(map[int]int)
    for _,v := range nums {
        if val,ok := m[v];ok{
            m[v] = val+1
        }else {
            m[v] = 1
        }
    }
    //此时m为统计好的各个数字出现次数的map
    //2、利用桶,下标表示出现的次数,val是个list,存放相同次数的数字。
    var bucket = make([][]int,len(nums)+1)
    for k,v := range m {
        if bucket[v] == nil {
            temp := []int{k}
            bucket[v] = temp
        }else {
            bucket[v] = append(bucket[v],k)
        }
    }
    //此时bucket是按照次数出现的桶
    //3、从后往前遍历通,拿到要出现的单词
    var result []int
    for i:=len(bucket)-1;i!=0&&k!=0;i-- {
        if bucket[i] != nil {
            result = append(result, bucket[i]...)
            k = k-len(bucket[i])
        }
    }
    return result
}

题目2:按照字符出现次数对字符串排序
451. Sort Characters By Frequency (Medium)

Input:
"tree"

Output:
"eert"

Explanation:
'e' appears twice while 'r' and 't' both appear once.
So 'e' must appear before both 'r' and 't'. Therefore "eetr" is also a valid answer.
//利用桶排序。
func frequencySort(s string) string {
    bt := []byte(s)
     //1、先统计各个字母出现的次数
     var m = make(map[byte]int)
     for _,v := range bt {
        if val,ok := m[v];ok{
            m[v] = val+1
        }else {
            m[v] = 1
        }
    }
    //此时m为统计好的各个字母出现次数的map
    //2、利用桶,下标表示出现的次数,val是个list,存放相同次数的字母。
    var bucket = make([][]byte,len(s)+1)
    for k,v := range m {
        if bucket[v] == nil {
            temp := []byte{k}
            bucket[v] = temp
        }else {
            bucket[v] = append(bucket[v],k)
        }
    }
     //此时bucket是按照次数出现的桶
    //3、从后往前遍历通,拿到要出现的单词
    var result []byte
    for i:=len(bucket)-1;i!=0;i-- {
        if bucket[i] != nil {
            for k:=0;k!=len(bucket[i]);k++ {
                for j:=0;j!=i;j++ {
                    result = append(result,bucket[i][k])
                }
            }
        }
    }
    return string(result)
}

3、双(多)指针+排序
问题:荷兰国旗问题
荷兰国旗包含三种颜色:红、白、蓝。

有三种颜色的球,算法的目标是将这三种球按颜色顺序正确地排列。

它其实是三向切分快速排序的一种变种,在三向切分快速排序中,每次切分都将数组分成三个区间:小于切分元素、等于切分元素、大于切分元素,而该算法是将数组分成三个区间:等于红色、等于白色、等于蓝色。
75. Sort Colors (Medium)

Input: [2,0,2,1,1,0]
Output: [0,0,1,1,2,2]
/*采用前后两个指针指向两端的颜色标记然后用一个遍历指针从前往后遍历,
遇到red或者blue则交换到相应red和blue指针的位置,
然后继续往前找(注意边界关系,
搜索指针找到red交换后要继续往前,找到blue的时候不能往前还要比较一次,
当搜索指针与blue相遇时也要比一次)*/

func sortColors(nums []int)  {
    l,r := 0,len(nums)-1;
    for i:=0;i<= r;{
        if nums[i] == 0 { //扫描到red
            swap(nums,i,l)
            l++
            i++
        }else if  nums[i] == 2 { //扫描到blue
            swap(nums,i,r)
            r--
        }else {
            i++
        }
    }
}

func swap(nums []int,i int, j int) {
    temp := nums[i]
    nums[i] = nums[j]
    nums[j] = temp
}

思考:如果是K个元素如此排序怎么办。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 220,492评论 6 513
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 94,048评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 166,927评论 0 358
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,293评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,309评论 6 397
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 52,024评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,638评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,546评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 46,073评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,188评论 3 340
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,321评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,998评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,678评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,186评论 0 23
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,303评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,663评论 3 375
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,330评论 2 358

推荐阅读更多精彩内容

  • 算法思想贪心思想双指针排序快速选择堆排序桶排序荷兰国旗问题二分查找搜索BFSDFSBacktracking分治动态...
    第六象限阅读 3,118评论 0 0
  • 1 初级排序算法 排序算法关注的主要是重新排列数组元素,其中每个元素都有一个主键。排序算法是将所有元素主键按某种方...
    深度沉迷学习阅读 1,413评论 0 1
  • 最近在读< >时,了解到了很多常用的排序算法,故写一篇读书笔记记录下这些排序算法的思路和实现. 冒泡排序 冒泡排序...
    SylvanasSun阅读 690评论 0 0
  • 数据结构与算法——快速排序 快速排序,顾名思义,它速度很快,针对一般应用中各种不同的输入都要比其他排序算法快很多,...
    sunhaiyu阅读 3,283评论 0 3
  • 所谓“一夫当关,万夫莫开”,占据地理上的优势可能比集结千军万马还重要,《孙子兵法》将“道、天、地、将、法”列为兵家...
    硕鼠无止阅读 2,181评论 5 19