算法基础

引用链接:
剑指offer题库
算法之剑指offer题目总结
2019 iOS面试题大全---全方面剖析面试
2018 iOS面试题---算法相关
1、七种常见的数组排序算法整理(C语言版本)
2、2019 算法面试相关(leetcode)--数组和链表
3、2019 算法面试相关(leetcode)--字符串
4、2019 算法面试相关(leetcode)--栈和队列
5、2019 算法面试相关(leetcode)--优先队列
6、2019 算法面试相关(leetcode)--哈希表
7、2019 算法面试相关(leetcode)--树、二叉树、二叉搜索树
8、2019 算法面试相关(leetcode)--递归与分治
9、2019 算法面试相关(leetcode)--贪心算法
10、2019 算法面试相关(leetcode)--动态规划(Dynamic Programming)
11、2019 算法面试相关(leetcode)--动态规划之背包问题

引用链接:
MARK: - 算法
十大编程算法助程序员走上高手之路
十大经典排序算法
1、冒泡排序:从第一个开始,往后比较相邻元素,交换位置,不交换时结束
2、选择排序:选择最小的交换,最后交换到前面的位置
3、插入排序:与前面排好序的对比,插入到前面
4、希尔排序:分治算法,二分增量排序(二分后继续二分,直到只有两个元素)
5、归并排序:分治算法,递归左右两边的排序,最后合并
6、快速排序:选择基准元素,递归左右两边的排序
7、堆排序:二叉树排序
8、计数排序:每个桶只存储单一键值(适合整数)
9、桶排序:每个桶存储一定范围的数值
10、基数排序:根据键值的每位数字来分配桶,从个位开始,然后十位,百位...
数据结构与算法

关于时间/空间复杂度,名词解释:
n:数据规模
k:"桶"的个数
Out-place:占用额外内存
In-place:占用常数内存,不占用额外内存
稳定性:排序后 2 个相等键值的顺序和排序之前它们的顺序相同

根据数据结构和算法思想的分类,《剑指 Offer》可以分为以下几种标签,可点击链接,查看题解(正在不断更新中):

引用:全部题目都提供动画解题思路,不用担心看不懂!



计数排序
假设有一个待排序的列表 [4, 2, 2, 8, 3, 3, 1],数据的范围是 1 到 8,计数排序的过程如下:

统计频率:
初始化计数数组 count,大小为 9(范围 0-8)。
遍历列表,统计每个元素的出现次数:
初始 count[element] = 0
count[element] = count[element] + 1
count[element] = 0 + 1,即:

for element in array {   //存在的添加,不存在的始终为默认值 0
     count[element] += 1 //将countArray数组中索引为 element 的值加 1。
}

count[0] = 0
count[1] = 1
count[2] = 2
count[3] = 2
count[4] = 1
count[5] = 0
count[6] = 0
count[7] = 0
count[8] = 1
计数数据次序:[0, 1, 2, 3, 4, 5, 6, 7, 8]。
计数数组分布:[0, 1, 2, 2, 1, 0, 0, 0, 1]。

累加频率:
将计数数组中的值累加,得到每个元素的最终位置:
countArray[i] = countArray[i] + countArray[i-1]
元素位置依次增加:在前面的位置数+当前的个数
count[0] = 0
count[1] = 1 + 0 = 1
count[2] = 2 + 1 = 3
count[3] = 2 + 3 = 5
count[4] = 1 + 5 = 6
count[5] = 0+ 6 = 6
count[6] = 0+ 6 = 6
count[7] = 0+ 6 = 6
count[8] = 1 + 6 = 7
累加后的计数数组:[0, 1, 3, 5, 6, 6, 6, 6, 7]。

放置元素:
初始化结果数组 output,count大小为 7。
遍历原始列表,根据计数数组中的位置信息,将元素放入结果数组:
原列表 [4, 2, 2, 8, 3, 3, 1]
位置i: i = count[4] - 1 = 6-1 = 5
位置i: i = count[2] - 1 = 3-1 = 2
位置i: i = count[2] - 1 = 2-1 = 1 这里的 count[2] 替换上面的结果
位置i: i = count[8] - 1 = 7-1 = 6
...
arr[5] = 4
arr[2] = 2
arr[1] = 2
arr[6] = 8
...
元素 4:count[4] = 6,放入 output[5],count[4] -= 1。
元素 2:count[2] = 3,放入 output[2],count[2] -= 1。
元素 2:count[2] = 2,放入 output[1],count[2] -= 1。
元素 8:count[8] = 7,放入 output[6],count[8] -= 1。
元素 3:count[3] = 5,放入 output[4],count[3] -= 1。
元素 3:count[3] = 4,放入 output[3],count[3] -= 1。
元素 1:count[1] = 1,放入 output[0],count[1] -= 1。
结果数组:[1, 2, 2, 3, 3, 4, 8]。

    //计数排序
    func countingSort(_ array: [Int]) -> [Int] {
        guard array.count > 0 else { return array }
        // 找到数组中的最大值
        // 创建一个计数数组,大小为最大值 + 1
        let maxElement = array.max() ?? 0
        var countArray = [Int](repeating:0, count: maxElement + 1)
        // 统计每个元素的出现次数:初始 countArray[element] = 0
        for element in array {
            countArray[element] += 1 //意思是:将countArray数组中索引为 element 的值加 1。
        }
        // 累加计数数组,确定每个元素的最终位置
        for i in 1..<countArray.count {
            countArray[i] += countArray[i-1]
        }
        // 创建一个临时数组存储排序结果
        // 从后向前遍历原数组,将元素放到正确的位置
        var sortedArray = [Int](repeating: 0, count: array.count)
        for element in array.reversed() {
            countArray[element] -= 1
            sortedArray[countArray[element]] = element
        }
        return sortedArray
    }
    func test_counting() {
        //示例使用
        let array = [4, 2, 2, 8, 3, 3, 1]
        let sortedArray = countingSort(array)
        print("排序后的数组: \(sortedArray)")
    }
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容