算法篇06、其他算法补充--贪心算法、LRU缓存替换策略算法等

740 阅读4分钟

本篇主要补充前面没有讲到的两道小问题,一道贪心算法问题,一道LRU缓存替换策略算法问题;

1、leetcode455--分发饼干

假设你是一位很棒的家长,想要给你的孩子们一些小饼干。但是,每个孩子最多只能给一块饼干。

对每个孩子 i,都有一个胃口值 g[i],这是能让孩子们满足胃口的饼干的最小尺寸;并且每块饼干 j,都有一个尺寸 s[j] 。如果 s[j] >= g[i],我们可以将这个饼干 j 分配给孩子 i ,这个孩子会得到满足。你的目标是尽可能满足越多数量的孩子,并输出这个最大数值。

示例 1:

输入: g = [1,2,3], s = [1,1]
输出: 1
解释: 
你有三个孩子和两块小饼干,3个孩子的胃口值分别是:1,2,3。
虽然你有两块小饼干,由于他们的尺寸都是1,你只能让胃口值是1的孩子满足。
所以你应该输出1。

题解如下所示,本题虽然题干描述看起来很麻烦,其实就是一道典型的贪心算法问题;

我们首先将小朋友的贪心指数排序,然后将饼干尺寸排序;如果最大尺寸的饼干没法满足最贪心的小朋友,那么这个小朋友就肯定不能满足他了,因为你想最大尺寸的饼干都没法满足了,其余饼干肯定也不能满足,此时就将小朋友数组的索引递减,去看能不能满足下一个小朋友,如果可以满足下一个小朋友,那么结果加1,将饼干数组和小朋友数组分别递减,去判断下一块饼干能不能满足下一个小朋友,依次循环直到饼干数组或者小朋友数组为空;

//leetcode 455 分发饼干
public int findContentChildren(int[] g, int[] s) {
    Arrays.sort(g);
    Arrays.sort(s);
    int gi = g.length - 1;
    int si = s.length - 1;
    int res = 0;
    while (gi >= 0 && si >= 0){
        if (s[si] >= g[gi]){
            res ++;
            si--;
            gi--;
        }else {
            gi--;
        }
    }
    return res;
}

2、leetcode146--LRU缓存机制

运用你所掌握的数据结构,设计和实现一个  LRU (最近最少使用) 缓存机制 。

实现 LRUCache 类:

LRUCache(int capacity) 以正整数作为容量 capacity 初始化 LRU 缓存; int get(int key) 如果关键字 key 存在于缓存中,则返回关键字的值,否则返回 -1 。 void put(int key, int value) 如果关键字已经存在,则变更其数据值;如果关键字不存在,则插入该组「关键字-值」。当缓存容量达到上限时,它应该在写入新数据之前删除最久未使用的数据值,从而为新的数据值留出空间。

题目描述中的LRUCache类应该都非常熟悉,在高速缓存的替换策略和虚拟内存的置换算法中LRU都是重点内容;

题解如下所示,我们借助LinkedHashMap这个类,这个类内部实现是有双向链表和哈希表共同实现的,可以按照插入顺序保存数据;

我们实现的LRUCache类中主要就是get和put方法;

get方法调用时,当LinkedHashMap中不存在此key时返回-1,否则就将此key对应的键值对刷新为最新访问过的,具体操作就是把原键值对删除,重新put保存一次,LinkedHashMap会自动将新插入的数据保存在最后;

put方法调用时,如果LinkedHashMap中已经存在此key对应的键值对了,就将原来的键值对删除,重新put最新的键值对,然后返回;如果不存在,首先检查LinkedHashMap是否满了,如果满了,先删除头部head的键值对,也就是最近最少使用的那个,这也是LRU设计的思想;删除完之后再将键值对保存进LinkedHashMap即可;

import java.util.LinkedHashMap;

//leetcode 146 LRU缓存机制
class LRUCache {
    int capacity;
    int size;
    LinkedHashMap<Integer,Integer> linkedHashMap = new LinkedHashMap<>();

    public LRUCache(int capacity) {
        this.capacity = capacity;
        this.size = 0;
    }

    public int get(int key) {
        if (!linkedHashMap.containsKey(key)){
            return -1;
        }
        makeRecentUse(key);
        return linkedHashMap.get(key);
    }

    private void makeRecentUse(int key) {
        int value = linkedHashMap.get(key);
        linkedHashMap.remove(key);
        linkedHashMap.put(key,value);
    }

    public void put(int key, int value) {
        if (linkedHashMap.containsKey(key)){
            linkedHashMap.remove(key);
            linkedHashMap.put(key,value);
            return;
        }

        if (linkedHashMap.size() == capacity){
            Integer head = linkedHashMap.keySet().iterator().next();
            linkedHashMap.remove(head);
        }
        linkedHashMap.put(key,value);
    }
}

题目来源出处:

来源:力扣(LeetCode) 链接:leetcode-cn.com/problemset/…