LRU Cache & Max Points on a Line & Valid Number

(1) LRU Cache

LRU简洁明了的算法描述[1],就是用一个双向链表+map,不用map查找的话就要遍历了。。。时间复杂度就上升了。双向链表的好处就是。。。用map定位到那个节点,然后很方便的移动或者删除啊什么的,单向就做不到啦,因为你要删除还要找prev。双向链表就不写了,用stl的list代替。[1]

list的spice方法[2]是适合这道题的主要因素!

class CacheNode{
public:
    int key;
    int value;
    CacheNode(int k, int v) : key(k) , value(v){}
};

class LRUCache{
private:
    int CacheSize;
    list<CacheNode> CacheList;
    unordered_map<int, list<CacheNode>::iterator> CacheMap;

public:
    LRUCache(int capacity) {
        CacheSize=capacity;
    }
    
    int get(int key) {
        if(CacheMap.find(key)!=CacheMap.end())
        {
            auto iter=CacheMap[key];
            CacheList.splice(CacheList.begin(),CacheList,iter);
            return CacheList.begin()->value;
        }
        else
            return -1;
    }
    
    void set(int key, int value) {
        if(CacheMap.find(key)==CacheMap.end())
        {
            if(CacheList.size()==CacheSize)
            {
                CacheMap.erase(CacheList.back().key);
                CacheList.pop_back();
            }
            CacheList.push_front(CacheNode(key,value));
            CacheMap[key]=CacheList.begin();
        }
        else
        {
            auto iter=CacheMap[key];
            CacheList.splice(CacheList.begin(),CacheList,iter);
            CacheList.begin()->value=value;
        }
    }
};

(2) Max Points on a Line

取定一个点points[i], 遍历其他所有节点, 然后统计斜率相同的点数,并求取最大值即可。[3]

class Solution {
public:
    int maxPoints(vector<Point> &points) {
        int len=points.size();
        if(len<=2)
            return len;
        unordered_map<double,int> slopeMap;
        int ret=0;
        
        for(int i=0;i<len;i++)
        {
            slopeMap.clear();
            slopeMap[INT_MIN]=0;
            int duplicate=1;
            for(int j=0;j<len;j++)
            {
                if(i==j)
                    continue;
                double slope=INT_MAX*1.0;
                if(points[i].x == points[j].x && points[i].y == points[j].y)
                {
                    duplicate++;
                    continue;
                }
                if(points[i].x!=points[j].x)
                    slope=1.0*(points[i].y - points[j].y)/(points[i].x - points[j].x);
                
                slopeMap[slope]++;
            }
            
            for(auto iter=slopeMap.begin();iter!=slopeMap.end();iter++)
                ret=max(ret,iter->second+duplicate);
        }
        return ret;
    }
};

(3) Valid Number

需要考虑很多边界情况,面试测试岗比较有用[4]。

另外对于比较多的分支情况用switch比if-else写起来直观得多:

class Solution {
private:
    string trim(const char *s) {
        string ret;
        if(strlen(s)==0)
            return ret;
        int i,j=strlen(s)-1;
        
        for(i=0;s[i]!='\0';i++)
            if(s[i]!=' ')
                break;
                
        if(s[i]=='\0')
            return ret;
            
        while(j>=0)
        {
            if(s[j]!=' ')
                break;
            j--;
        }
        
        for(int k=i;k<=j;k++)
            ret.push_back(s[k]);
        return ret;
    }
    
public:
    bool isNumber(const char *s) {
        if(s==NULL)
            return false;
        string str=trim(s);
        if(str.size()==0)
            return false;
        
        bool hadDot=false;
        bool hadE=false;
        
        for(int i=0;i<str.size();i++)
        {
            switch(str[i])
            {
                case '.':
                    if(hadDot || hadE || (i==0 || !(str[i-1]>='0'&&str[i-1]<='9')) && (i==str.size()-1 || !(str[i+1]>='0'&&str[i+1]<='9')))    
                        return false;
                    hadDot=true;
                    break;
                case '+':
                case '-':
                    if(i>0 && (str[i-1]!='e'&& str[i-1]!='E') || (i==str.size()-1 || !((str[i+1]>='0'&&str[i+1]<='9') || str[i+1]=='.')))
                        return false;
                    break;
                case 'e':
                case 'E':
                    if(hadE || i==str.size()-1 || i==0)
                        return false;
                    hadE=true;
                    break;
                case '0':
                case '1':
                case '2':
                case '3':
                case '4':
                case '5':
                case '6':
                case '7':
                case '8':
                case '9':
                    break;
                default:
                    return false;
            }
        }
        return true;
    }
};
此题还有一种用有限状态机解决的很简洁的方法[5]。



参考:

[1] http://www.cnblogs.com/x1957/p/3485053.html

[2] http://www.cplusplus.com/reference/list/list/splice/

[3 ]http://blog.csdn.net/doc_sgl/article/details/17103427

[4] http://blog.csdn.net/linhuanmars/article/details/23809661

[5] http://www.cnblogs.com/chasuner/p/validNumber.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值