/**
贪心算法
问题引入:
有1元、2元、5元、10元、20元、50元、100元
的钞票无穷多张,现使用这些钞票支付X元
求问最少需要多少张钞票
贪心法:遵循某种规律,不断贪心的选取当前最优策略的算法设计方法
**/
#include
#include
using namespace std;
int main(){
int total_money;
cin>>total_money;
int a[]={1,2,5,10,20,50,100};
int num=0;
while(total_money>0){
for(unsigned int i=6;i>=0;i--){
if(a[i]<=total_money){
num++;
total_money-=a[i];
break;
}
}
}
cout<<"the total num of money is: "<
/**
leetcode 455. 分发饼干
假设你是一位很棒的家长,想要给你的孩子们一些小饼干
但是,每个孩子最多只能给一块饼干
对每个孩子 i ,都有一个胃口值 gi 这是能让孩子们满足胃口的饼干的最小尺寸
并且每块饼干 j ,都有一个尺寸 sj
如果 sj >= gi ,我们可以将这个饼干 j 分配给孩子 i ,这个孩子会得到满足
你的目标是尽可能满足越多数量的孩子,并输出这个最大数值
注意:
你可以假设胃口值为正
一个小朋友最多只能拥有一块饼干
**/
#include
#include
#include
using namespace std;
class Solution {
public:
int findContentChildren(vector& g, vector& s) {
sort(g.begin(),g.begin()+g.size(),less());
sort(s.begin(),s.begin()+s.size(),less());
int content_num=0;
int p1=0,p2=0;
// 指针p1和p2分别指向数组g和s
// 首先尝试让胃口值小的孩子满足,如果胃口值小的孩子
// 无法被满足,则胃口值大的孩子一定不能被满足
while(p2 g1;
g1.push_back(1);
g1.push_back(2);
g1.push_back(3);
vector s1;
s1.push_back(1);
s1.push_back(2);
Solution s;
cout<
https://www.bilibili.com/video/av29912609/?p=3
/**
leetcode 376. 摆动序列
如果连续数字之间的差严格地在正数和负数之间交替,则数字序列称为摆动序列
第一个差(如果存在的话)可能是正数或负数。少于两个元素的序列也是摆动序列。
例如, [1,7,4,9,2,5] 是一个摆动序列,因为差值 (6,-3,5,-7,3) 是正负交替出现的
相反, [1,4,7,2,5] 和 [1,7,4,5,5] 不是摆动序列,
第一个序列是因为它的前两个差值都是正数,第二个序列是因为它的最后一个差值为零。
给定一个整数序列,返回作为摆动序列的最长子序列的长度
通过从原始序列中删除一些(也可以不删除)元素来获得子序列
剩下的元素保持其原始顺序。
所要求的的时间复杂度为 O(N)
输入: [1,17,5,10,13,15,10,5,16,8]
输出: 7
使用额外的vector来存储具有最大长度的摇摆子序列
如果输入的vector中仅仅包含一个元素,则它必然是摇摆序列
如果输入的vecto中包含两个元素,
如果两个元素相等,则摇摆序列的长度为1
否则无论是升序还是降序,摇摆序列的长度都为2
当vector的长度大于2时
[1,17,5,10,13,15,10,5,16,8]
当序列出现连续的递增或者递减时,则只需要一直寻找到单调递增或者单调递减的端点即可
**/
#include
#include
using namespace std;
class Solution {
public:
int wiggleMaxLength(vector& nums) {
vector result;
unsigned int i=0;
bool flag=false;
while(iresult[result.size()-1]){
result.push_back(nums[i]);
i++;
while(i=result[result.size()-1]){
result[result.size()-1]=nums[i];
i++;
}
continue;
}
if(nums[i] my;
for(unsigned int i=0;i<2;i++){
my.push_back(a[i]);
}
Solution s;
cout<
/**
leetcode 402. 移掉K位数字
给定一个以字符串表示的非负整数 num
移除这个数中的 k 位数字,使得剩下的数字最小。
假设给定一串固定的字符,则它们所能构成的最小字符串
是将所有的字符进行降序排列
C++ string 模板类删除字符串的方法
string.erase(pos,n)
删除从pos开始的连续n个字符,字符的索引下标从0开始
如果只需要删除一个字符,则n=1
算法:
维护单调栈stack,不断扫描输入的字符串,并根据栈顶元素
判断是否将字符入栈或者将栈顶元素出栈
**/
#include
#include
#include
using namespace std;
class Solution {
public:
string removeKdigits(string num, int k) {
if(num.length()==0 or num.length()==k){
return "0";
}
stack helper_stack;
int index=0;
while(index0 and !helper_stack.empty() and helper_stack.top()>num[index]){
helper_stack.pop();
k--;
}
helper_stack.push(num[index]);
index++;
}
}
}
// cout<<"outside while loop "<=0;i--){
result+=result2[i];
// 将栈中的字符串逆序
// cout<<"each iteration "<0){
// k大于0,字符串都是降序排列,则从最后一位开始去除
while(k>0){
k--;
result=result.erase(result.length()-1,1);
}
}
// 去除头部的'0'
while(result[0]=='0'){
// cout<<"during deleting "<
/**
leetcode 55 跳跃游戏
给定一个非负整数数组,你最初位于数组的第一个位置
数组中的每个元素代表你在该位置可以跳跃的最大长度
判断你是否能够到达最后一个位置。
算法1:
暴力给出所有可能的情况+剪枝
算法2:
贪心算法,每次跳跃到的位置应该是走到该位置上之后能够走得最远的位置
**/
#include
#include
using namespace std;
class Solution {
public:
bool canJump(vector& nums) {
if(nums.size()<=1){
return true;
}
if(nums[0]==0){
return false;
}
vector index_avai;
for(unsigned int i=0;i=nums.size()){
return true;
}
for(unsigned int j=max_valid;j<=nums[index]+index;j++){
index_avai[j]=true;
}
max_valid=nums[index]+index;
index++;
}
}
return index_avai[index_avai.size()-1];
}
};
int main(){
int a[5]={3,2,1,0,4};
vector a1;
for(unsigned int i=0;i<5;i++){
a1.push_back(a[i]);
}
Solution s;
cout<
/**
leetcode 55 跳跃游戏
给定一个非负整数数组,你最初位于数组的第一个位置
数组中的每个元素代表你在该位置可以跳跃的最大长度
判断你是否能够到达最后一个位置。
算法1:
暴力给出所有可能的情况+剪枝
算法2:
贪心算法,每次跳跃到的位置应该是走到该位置上之后能够走得最远的位置
**/
#include
#include
using namespace std;
class Solution {
public:
bool canJump(vector& nums) {
if(nums.size()<=1){
return true;
}
int index=0;
int next_index=-1;
int max_step=-1;
while(index=nums.size()){
return true;
}
for(int i=index+1;i<=index+nums[index];i++){
if(i+nums[i]>=max_step){
max_step=i+nums[i];
next_index=i;
}
}
index=next_index;
// 使用贪心算法找出下一步应该跳跃到的位置
//cout<<"my here"< a1;
for(unsigned int i=0;i<5;i++){
a1.push_back(a[i]);
}
Solution s;
cout<
/**
leetcode 45 跳跃游戏 II
同样是使用贪心算法,尽可能的跳到更远的地方
**/
#include
#include
using namespace std;
class Solution {
public:
int jump(vector& nums) {
if(nums.size()<=1){
return 0;
}
int jump_count=0;
int index=0;
int max_step=-1;
int next_index=-1;
while(index=nums.size()){
return ++jump_count;
}
for(int i=index+1;i<=index+nums[index];i++){
if(i+nums[i]>=max_step){
max_step=i+nums[i];
next_index=i;
}
}
index=next_index;
jump_count++;
}
return jump_count;
}
};
int main(){
int a[5]={2,3,1,1,4};
vector a1;
for(unsigned int i=0;i<5;i++){
a1.push_back(a[i]);
}
Solution s;
cout<
/**
leetcode 452. 用最少数量的箭引爆气球
输入:
[[10,16], [2,8], [1,6], [7,12]]
首先根据二维数组每个点的xmin坐标为key对二维数组进行排序
1 6
2 8
7 12 // 由于7>6 ,故而不能被添加到前面的子集合中
10 16
right_min 用以记录能够进行合并的所有子区间的最小右端点
并不断更新right_min值
**/
#include
#include
#include
using namespace std;
bool cmp(vector a,vector b){
// 重载函数
if(a[0]b[0]){
return false;
}
// a[0]==b[0]
return a[1] >& points) {
if(points.size()<=1){
return points.size();
}
sort(points.begin(),points.end());
int arrow_count=1;
int index=1;
int continus_flag=false;
int right_min=points[0][1];// 记录能够合并的区间的右端点的最小值
// int right_max=points[0][1];// 记录能够合并的区间的右端点的最大值
while(indexright_max){
// right_max=points[index][1];
// }
// }
index++;
}
if(index==points.size()){
return arrow_count;
}
arrow_count++;
right_min=points[index][1];
// right_max=points[index][1];
index++;
continus_flag=false;
}
return arrow_count;
}
};
int main(){
int a[][2]={3,9,7,12,3,8,6,8,9,10,2,9,0,9,3,9,0,6,2,8};
vector > b;
for(int i=0;i<10;i++){
vector temp;
temp.push_back(a[i][0]);
temp.push_back(a[i][1]);
b.push_back(temp);
}
Solution s;
cout<<"the total count is: "<