剑指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刷题排序算法的主要内容,如果未能解决你的问题,请参考以下文章