除夕做的题,贴春联,做饭的时间占用了,,做了十道题,总结之
146.146-LRU Cache-Difficulty: Hard
Design and implement a data structure for Least Recently Used (LRU) cache. It should support the following operations: get
and set
.
get(key)
- Get the value (will always be positive) of the key if the key exists in the cache, otherwise return -1.
set(key, value)
- Set or insert the value if the key is not already present. When the cache reached its capacity, it should invalidate the least recently used item before inserting a new item.
方法一
思路
模拟LRU catche,最后使用的数据最先删除(如果空间满)
博主开始使用两个链表操作,然后超时,原因应该是remove和add,insert过多,确实没有必要,可以实现,但是超时
IList<int> _value = new List<int>();
IList<int> _key = new List<int>();
int capacity = 0;
public test146(int capacity)
{
this.capacity = capacity;
}
public int Get(int key)
{
if (_key.Contains(key))
{
int index = _key.IndexOf(key);
int key_temp = _key[index];
int value_temp = _value[index];
_key.RemoveAt(index);
_value.RemoveAt(index);
_key.Add(key_temp);
_value.Add(value_temp);
return value_temp;
}
else
return -1;
}
public void Set(int key, int value)
{
if (_key.Contains(key))
{
_value[_key.IndexOf(key)] = value;
}
else
{
if (_value.Count + 1 > capacity)
{
_key.RemoveAt(0);
_value.RemoveAt(0);
_key.Add(key);
_value.Add(value);
}
else
{
_key.Add(key);
_value.Add(value);
}
}
}
方法二
思路
双链表
参考:
https://leetcode.com/discuss/81106/java-easy-version-to-understand
1.The key to solve this problem is using a double linked list which enables us to quickly move nodes.2.The LRU cache is a hash table of keys and double linked nodes. The hash table makes the time of get() to be O(1). The list of double linked nodes make the nodes adding/removal operations O(1).
class Node { int key; int value; Node pre; Node next;
public Node(int key, int value) {
this.key = key;
this.value = value;
}
}public class LRUCache {
HashMap<Integer, Node> map; int capicity, count; Node head, tail;
public LRUCache(int capacity) {
this.capicity = capacity;
map = new HashMap<>();
head = new Node(0, 0);
tail = new Node(0, 0);
head.next = tail;
tail.pre = head;
head.pre = null;
tail.next = null;
count = 0;
}
public void deleteNode(Node node) {
node.pre.next = node.next;
node.next.pre = node.pre;
}
public void addToHead(Node node) {
node.next = head.next;
node.next.pre = node;
node.pre = head;
head.next = node;
}
public int get(int key) {
if (map.get(key) != null) {
Node node = map.get(key);
int result = node.value;
deleteNode(node);
addToHead(node);
return result;
}
return -1;
}
public void set(int key, int value) {
if (map.get(key) != null) {
Node node = map.get(key);
node.value = value;
deleteNode(node);
addToHead(node);
} else {
Node node = new Node(key, value);
map.put(key, node);
if (count < capicity) {
count++;
addToHead(node);
} else {
map.remove(tail.pre.key);
deleteNode(tail.pre);
addToHead(node);
}
}
}
方法三
思路
键值对KeyValuePair作为Dictionary的value
参考:
https://miafish.wordpress.com/2015/01/27/leetcode-ojc-lru-cache/
public class LRUCache {
public class Node
{
public KeyValuePair<int, int> KeyValue { get; set; }
public Node Next { get; set; }
public Node Previous { get; set; }
public Node(int key, int value)
{
this.KeyValue = new KeyValuePair<int,int>(key, value);
Next = null;
Previous = null;
}
}
private readonly int capacity;
private int count;
private readonly Node head;
private readonly Dictionary<int, Node> myDictionary;
public LRUCache(int capacity)
{
head = new Node(-1, -1);
head.Next = head;
head.Previous = head;
this.capacity = capacity;
myDictionary = new Dictionary<int, Node>();
}
public int Get(int key)
{
Node node;
myDictionary.TryGetValue(key, out node);
if (node == null)
{
return -1;
}
this.MoveItToFirstElementAfterHead(node);
return node.KeyValue.Value;
}
public void Set(int key, int value)
{
Node node;
myDictionary.TryGetValue(key, out node);
if (node == null)
{
if (this.count == this.capacity)
{
// remove the last element
myDictionary.Remove(head.Previous.KeyValue.Key);
head.Previous = head.Previous.Previous;
head.Previous.Next = head;
count--;
}
// create new node and add to dictionary
var newNode = new Node(key, value);
myDictionary[key] = newNode;
this.InsertAfterTheHead(newNode);
// increase count
count++;
}
else
{
node.KeyValue = new KeyValuePair<int, int>(key, value);
this.MoveItToFirstElementAfterHead(node);
}
}
private void MoveItToFirstElementAfterHead(Node node)
{
RemoveCurrentNode(node);
this.InsertAfterTheHead(node);
}
private void InsertAfterTheHead(Node node)
{
// insert after the head
node.Next = this.head.Next;
node.Previous = this.head;
this.head.Next.Previous = node;
this.head.Next = node;
}
private static void RemoveCurrentNode(Node node)
{
// remove current node
node.Previous.Next = node.Next;
node.Next.Previous = node.Previous;
}
}
149.149-Max Points on a Line-Difficulty: Hard
Given n points on a 2D plane, find the maximum number of points that lie on the same straight line.思路
找到同一行上最多的points数目,包括任意斜行
博主真的没想到会利用斜率。。。斜率相同即在同一行
参考:
https://leetcode.com/discuss/57464/accepted-java-solution-easy-to-understand
/**
* Definition for a point.
* public class Point {
* public int x;
* public int y;
* public Point() { x = 0; y = 0; }
* public Point(int a, int b) { x = a; y = b; }
* }
*/
public class Solution {
public int MaxPoints(Point[] points) {
if(points.Length <= 0) return 0;
if(points.Length <= 2) return points.Length;
int result = 0;
for(int i = 0; i < points.Length; i++){
Hashtable hm = new Hashtable();
int samex = 1;
int samep = 0;
for(int j = 0; j < points.Length; j++){
if(j != i){
if((points[j].x == points[i].x) && (points[j].y == points[i].y)){
samep++;
}
if(points[j].x == points[i].x){
samex++;
continue;
}
double k = (double)(points[j].y - points[i].y) / (double)(points[j].x - points[i].x);
if(hm.ContainsKey(k)){
hm[k]=(int)hm[k] + 1;
}else{
hm.Add(k, 2);
}
result = Math.Max(result, (int)hm[k] + samep);
}
}
result = Math.Max(result, samex);
}
return result;
}
}
150.150-Evaluate Reverse Polish Notation-Difficulty: Medium
Evaluate the value of an arithmetic expression in Reverse Polish Notation.
Valid operators are +
, -
, *
, /
. Each operand may be an integer or another expression.
Some examples:
["2", "1", "+", "3", "*"] -> ((2 + 1) * 3) -> 9
["4", "13", "5", "/", "+"] -> (4 + (13 / 5)) -> 6
思路
利用栈,是数压栈,是运算符弹出两个一个伪算式右侧数一个为左侧进行运算,最后栈里剩的数就是结果
public class Solution {
public int EvalRPN(string[] tokens) {
Stack<int> stack = new Stack<int>();
for (int i = 0; i < tokens.Length; i++)
{
if (tokens[i] != "+" && tokens[i] != "-" && tokens[i] != "*" && tokens[i] != "/")
{
stack.Push(int.Parse(tokens[i]));
}
else
{
int r = stack.Peek();
stack.Pop();
int l = stack.Peek();
stack.Pop();
switch (tokens[i])
{
case "+":
stack.Push(l + r);
break;
case "-":
stack.Push(l - r);
break;
case "*":
stack.Push(l * r);
break;
case "/":
stack.Push(l / r);
break;
}
}
}
return stack.Peek();
}
}