博客园  :: 首页  :: 新随笔  :: 管理

10.贪心、模拟

Posted on 2021-03-29 21:33  wsg_blog  阅读(96)  评论(0编辑  收藏  举报

Index LeetCode

贪心

贪心算法或贪心思想采用贪心的策略,保证每次操作都是局部最优的,从而使最后得到的结果是全局最优的。

455.分发饼干[easy]

每个孩子都有自己的饥饿度,一堆饼干大小不同,且每个孩子只能分一个饼干,多少孩子可以吃饱
思路是先对vector数组排序,while循环遍历,符合条件 child++ 最后return

int findContentChildren(vector<int> children, vector<int>& cookies) {
  sort(children.begin(), children.end());
  sort(cookies.begin(), cookies.end());
  int child = 0, cookie = 0;
  while (child < children.size() && cookie < cookies.size()) {
    if (children[child] <= cookies[cookie]) ++child;
    ++cookie;
  }
  return child;
}
BM95.分发糖果问题(135.分发糖果)[hard]

分发糖果问题 每人必须要有一个,且分数高的要比左右的人的糖果多
思路:先初始化糖果数组为1,正反两遍遍历

int candy(vector<int>& ratings) {
   //思路 正反遍历
  int size = ratings.size();
  if(size < 2){
    return size;
  }
  vector<int> num(size, 1);   //把所有的糖果都初始化为1
  for(int i=1; i<size; i++)
  {
    if(ratings[i]>ratings[i-1]){
      num[i]=num[i-1]+1;          //这里是重点
    }
  }
  for(int i=size-1; i>0; i--)
  {
    if(ratings[i-1]>ratings[i]){
      num[i-1]=max(num[i-1],num[i]+1);        //这里是重点
    }
  }
  return accumulate(num.begin(), num.end(), 0);   //这里也是
}
BM96.主持人调度(二)[medium]

输入:2,[[1,2],[2,3]],2,[[1,3],[2,4]]
输出:1,2
排序+遍历比较

int minmumNumberOfHost(int n, vector<vector<int>>& startEnd){
  vector<int> start;
  vector<int> end;
  for(int i=0; i<n; i++){
    start.push_back(startEnd[i][0]);
    end.push_back(startEnd[i][1]);
  }
  //分别对开始和结束时间排序
  sort(start.begin(), start.end());
  sort(end.begin(), end.end());
  int res=0, j=0;
  for(int i=0; i<n; i++){
    if(start[i] >= end[j])  //新开始的节目大于上一轮结束的时间,主持人不变
      j++;
    else
      res++;  //主持人增加
  }
  return res;
}

模拟

BM97.旋转数组[medium]

输入:6,2,[1,2,3,4,5,6]
输出:[5,6,1,2,3,4]
三次reverse()

vector<int> solve(int n, int m, vector<int>& a){
  m=m%n;  //取余,因为每次长度为n的旋转数组相当于没有变化
  reverse(a.begin(), a.end());
  reverse(a.begin(), a.begin()+m);
  reverse(a.begin()+m, a,end());
  return a;
}
BM98.螺旋矩阵(54.螺旋矩阵)[medium]

说明:给你一个 m 行 n 列的矩阵 matrix ,请按照 顺时针螺旋顺序 ,返回矩阵中的所有元素。
输入:matrix = [[1,2,3],[4,5,6],[7,8,9]]
输出:[1,2,3,6,9,8,7,4,5]

vector<int> spiralOrder(vector<vector<int>>& matrix){
  int left=0, right=matrix[0].size()-1, top=0, bottom=matrix.size()-1;
  vector<int> res;
  while(true){
    for(int i=left; i<=right; i++) res.push_back(matrix[top][i]);
    if(++top > bottom) break;
    for(int i=top; i<=bottom; i++) res.push_back(matrix[i][right]);
    if(--right < left) break;
    for(int i=right; i >= left; i--) res.push_back(matrix[bottom][i]);
    if(--bottom < top) break;
    for(int i=bottom; i >= top; i--) res.push_back(matrix[i][left]);
    if(++left > right) break;
  }
  return res;
}
BM99.顺时针旋转矩阵(48.旋转图像)[medium]

输入:matrix = [[1,2,3],[4,5,6],[7,8,9]]
输出:[[7,4,1],[8,5,2],[9,6,3]]
说明:给定一个 n × n 的二维矩阵 matrix 表示一个图像。请你将图像顺时针旋转 90 度。
先矩阵转置,再按每行反转

vector<vector<int>> roate(vector<vector<int>>& matrix){
  int n=matrix.size();  
  for(int i=0; i<n; i++)  //矩阵转置
    for(int j=0; j<i; j++){
      swap(matrix[i][j], matrix[j][i]);
    }
  for(int i=0; i<n; i++){  //每行反转
    reverse(matrix[i].begin(), matrix[i].end());
  }
}
BM100.设计LRU缓存结构(164.LRU缓存)[medium]

输入:["LRUCache", "put", "put", "get", "put", "get", "put", "get", "get", "get"][[2], [1, 1], [2, 2], [1], [3, 3], [2], [4, 4], [1], [3], [4]]
输出:[null, null, null, 1, null, -1, null, -1, 3, 4]
说明:请你设计并实现一个满足 LRU (最近最少使用) 缓存 约束的数据结构,redis常用的数据缓存之一。

list<pair<int, int>> cache;  //数据缓存及排序
unordered_map<int, list<pair<int, int>>::iterator> key2node;  //节点索引
int capacity;  //最大容量
LRUCache(int capacity):capacity(capacity) {}
int get(int key){
  if(key2node.find(key) == key2node.end()) return -1;
  pair<int, int> node=*key2node[key];
  cache.erase(key2node[key]);
  cache.push_front(node);
  key2node[key]=cache.begin();
  return node.second;
}
void put(int key, int value){
  pair<int, int> newNode=std::make_pair(key, value);
  
  if(key2node.count(key)){
    cache.erase(key2node[key]);
  }else{
    if(key2node.size() == capacity){  //删除最后一个数据
      key2node.erase(cache.back().first);
      cache.pop_back();
    }
  }
  cache.push_front(newNode);  //插入新节点到头部
  key2node[key]=cache.begin();
}
BM101.设计LFU缓存结构(460.LFU缓存)[hard]

输入:["LFUCache", "put", "put", "get", "put", "get", "get", "put", "get", "get","get"][[2], [1, 1], [2, 2], [1], [3, 3], [2], [3], [4, 4], [1], [3], [4]]
输出:[null, null, null, 1, null, -1, 3, null, -1, 3, 4]
说明:void put(int key, int value) - 如果键 key 已存在,则变更其值;如果键不存在,请插入键值对。当缓存达到其容量 capacity 时,则应该在插入新项之前,移除最不经常使用的项。在此问题中,当存在平局(即两个或更多个键具有相同使用频率)时,应该去除 最近最久未使用 的键。
为了确定最不常使用的键,可以为缓存中的每个键维护一个 使用计数器。使用计数最小的键是最久未使用的键。