剑指offer刷题排序算法

Posted 非晚非晚

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了剑指offer刷题排序算法相关的知识,希望对你有一定的参考价值。

记录在Leetcode刷《剑指offer》的笔记,希望提高自己的算法基础和编程水平。这一篇文章刷的是排序算法的题目集合,在CSDN做一下记录,随时更新,一起学习吧。

刷题链接:https://leetcode-cn.com/leetbook/read/illustration-of-algorithm/55frat/

1. 剑指 Offer 40. 最小的 k 个数

  • 题目

在这里插入图片描述

  • 提交答案1

思路:先取k个数,然后插入进行插入排序。

class Solution {
public:
    vector<int> getLeastNumbers(vector<int>& arr, int k) {
        if(k == 0) 
        {
            vector<int> tmp(0,0);
            return tmp;
        }
        vector<int>tmp(arr.begin(), arr.begin() + k);
        sort(tmp.begin(), tmp.end());
        for(int i = k; i < arr.size();i++)
        {
            if(arr[i] >= tmp[k - 1]) continue;//数值太大
            if(arr[i] <= tmp[0]) //开头的位置
            {
                tmp.pop_back();
                tmp.insert(tmp.begin(), 1, arr[i]);
                continue;
            }
            tmp.pop_back();//末尾删除
            auto j = tmp.end();//迭代器
            j--;
            while(arr[i] < *j)
            {
                j--;
            }
            j++;//注意插入的位置
            tmp.insert(j,1,arr[i]);//j的前面插入1个arr[i]元素
        }
        return tmp;
    }
};
  • 提交答案2

思路:直接对输入进行排序。这种做法好像没有注意到考察的重点啊!

class Solution {
public:
    vector<int> getLeastNumbers(vector<int>& arr, int k) {
        sort(arr.begin(),arr.end());
        vector<int> tmp(arr.begin(),arr.begin() + k);
        return tmp;
    }
};

2. 剑指 Offer 41. 数据流中的中位数

  • 题目
    在这里插入图片描述

  • 提交答案

思路:插入并且排序

class MedianFinder {
private:
    vector<int> myNum;
public:
    /** initialize your data structure here. */
    MedianFinder() {
    }
    
    void addNum(int num) {
        if(myNum.size() == 0){myNum.push_back(num);return;}
        auto p = myNum.end();
        while(p != myNum.begin() && (*(p-1) > num))
        {
            p--;
        }
        myNum.insert(p, 1, num);
    }
    
    double findMedian() {
        int len = myNum.size();
        if(len % 2 == 0)
        {
            return (myNum[len/2] + myNum[len/2 - 1]) /2.0;
        }
        else
        return myNum[len/2];
    }
};

3. 剑指 Offer 45. 把数组排成最小的数

  • 题目
    在这里插入图片描述

  • 提交答案

思路:这里看了一下解析的答案。这里需要理解string类型的排序(x + y < y + x;则x应该排在前面。)。这里使用的是冒泡排序。

class Solution {
public:
    string minNumber(vector<int>& nums) {
        vector<string>str;
        for(auto x : nums)
            str.push_back(to_string(x));
        for(int i = 0; i < str.size(); i++)//冒泡排序
            for(int j = i + 1; j < str.size(); j++)
            {
                if(str[i] + str[j] > str[j] + str[i])
                {
                    swap(str[i], str[j]);
                    continue;
                }
            }
        string tmp;
        for(auto x : str)
            tmp += x;
        return tmp;
    }
};

4. 剑指 Offer 61. 扑克牌中的顺子

  • 题目
    在这里插入图片描述

  • 提交答案

思路:先排序,遍历数组。根据0的个数来进行判断。

class Solution {
public:
    bool isStraight(vector<int>& nums) {
        sort(nums.begin(),nums.end());
        int i = 0;
        for(i = 0; i < nums.size(); i++)
        {
            if(nums[i] !=0)break;
            if(i >= 3)return true;
        }
        for(int j = i; j < nums.size() - 1; j++)//剔除相同元素
        {
            if(nums[j] == nums[j+1])return false;
        }
        int len = nums[4] - nums[i];
        if((len <= 4) && (len >= 4 - i))
        	return true;
        return false;
    }
};
  • 题目解析

解析中应用了unordered_set,不插入0(大小王),。求最大值和最小值,有重复的直接跳出。基本思想是一致的,只是方法不一样。


class Solution {
public:
    bool isStraight(vector<int>& nums) {
        unordered_set<int> repeat;
        int ma = 0, mi = 14;
        for(int num : nums) {
            if(num == 0) continue; // 跳过大小王
            ma = max(ma, num); // 最大牌
            mi = min(mi, num); // 最小牌
            if(repeat.find(num) != repeat.end()) return false; // 若有重复,提前返回 false
            repeat.insert(num); // 添加此牌至 Set
        }
        return ma - mi < 5; // 最大牌 - 最小牌 < 5 则可构成顺子
    }
};

以上是关于剑指offer刷题排序算法的主要内容,如果未能解决你的问题,请参考以下文章

剑指 Offer(第 2 版)刷题 | 03. 数组中重复的数字

剑指offer刷题查找算法

剑指offer刷题01

剑指offer 刷题 01

剑指offer刷题记录

剑指Offer刷题总结