C++ notes

群里看到一个很有趣的东西

int a=(int)((int*)0+4);

乍一看似乎狂拽酷炫,后来发现int和int 之间转化也是地址值的直接转化,(int)0先变成地址值为0的指针(或者称职NULL,VS认为是等价的),然后指针+4相当于+4*sizeof(int), 相当于地址值+16,然后将0x00000010(VS似乎是32bit的,32bit,然后直接将地址值转化为int就是值),a=16

看到微博粉丝狂魔陈立人发了一个面试题,求K linklist的交集,返回一个linklist,类似于Merge K linklist,当时需要用heap优化才能AC。

一开始写个代码,大概想了下可以heap,但是后来发现似乎不行,因为merge是把数据删掉,同时copy到result linklist里,但是这里如果不是全部相等,需要将非max的val对应的linklist指针
后移,同时max的还要保留,heap也必须是maxheap,似乎是不行,于是只好写个朴素的O(n)的遍历了。不确定是否bug free

struct ListNode
{
    int val;
    ListNode* next;
    ListNode(int x):val(x), next(NULL)
    {
        //val=x;
        //next=NULL;
    }
};

bool AtLeastOnePointNULL()
{
    for(int i=0;i<p.size();i++)
        if(p[i]==NULL) 
            return true;
    return false;
}

ListNode* Intersection(vector<ListNode*> ListHead)
{
    vector<ListNode*> p;
    //vector<int> nextp;
    ListNode* resulthead=NULL, *resulttail;

    if(ListHead.size()==0)
        return resulthead;
    //vector<int> curval;
    for(int i=0;i<ListHead.size();i++)
        p.push_back(ListHead[i]);//curval.push_back(ListHead[i]->val);
    //make_heap(curval.begin(),curval.end());//max heap default
    bool first=true;
    while(1)
    {
        if(AtLeastOnePointNULL())
            break;
        int max=p[0]->val;//at least one linklist
        bool modified=false;
        for(int i=1;i<p.size();i++)
            if(p[i]->val>max)
                max=p[i]->val,modified=true;
        if(modified==false)//at least one linklist        
        {
            if(first==true)
            {
                resulthead=new ListNode(p[0]->val);
                resulttail=resulthead;
                first==false;
            }
            else
            {
                resulttail->next=new ListNode(p[0]->val),resulttail=resulttail->next;
            }
            for(int i=0;i<p.size();i++)
                p[i]=p[i]->next;
        }
        else
        {
            for(int i=0;i<p.size();i++)
            {
                if(p[i]->val<max)
                    p[i]=p[i]->next;
            }
        }
    }

    return resulthead;
}

昨晚和瞿神讨论这道算法,发现似乎我的稍微有点笨了点,可以一次遍历第二遍遍历的次数,这个时间复杂度不能从循环的角度来计算,因为条件判断比较复杂。
这道应该从结点的某个操作次数累加来看,例如K个Linklist共N个结点,然后每个结点一定只是后移一次,这里面主要就是point后移操作,只要一个linklist空了就结束,
时间复杂度是O(N)

ListNode* Intersection(vector<ListNode*> ListHead)
{
    vector<ListNode*> p;
    vector<int> curmax;

    ListNode* head=NULL,*tail;

    if(ListHead.size()==0)
        return head;
    for(int i=0;i<ListHead.size();i++)
        p.push_back(ListHead[i]);
    bool first=false;
    while(1)
    {
        if(AtLeastOnePointNULL())
            break;
        curmax.push_back(0);
        for(int i=1;i<p.size();i++)
        {
            if(p[i]->val<p[curmax[0]]->val)//at least one ele in curmax
                p[i]=p[i]->next;
            else if(p[i]->val==p[curmax[0]]->val)
                curmax.push_back(i);
            else//update max
            {
                for(int j=0;j<curmax.size();j++)
                    p[curmax[j]]=p[curmax[j]]->next;
                curmax.clear();
                curmax.push_back(i);
            }
        }
        if(curmax.size()==ListHead.size())
        {
            if(first==false)
            {
                head=new ListNode(p[0]->val);
                tail=head;
                first==true;
            }
            else
            {
                tail->next=new ListNode(p[0]->val),tail=tail->next;
            }
            for(int i=0;i<p.size();i++)
            {
                p[i]=p[i]->next;
            }
        }
    }
    return head;
}

今天碰到一个subfigure的问题,用BMC Bio的模板怎么改都改不好,主要是width height加不进去,识别不了,因此两个subfigure是上下排列的。
周老师过来问我屏幕怎么两个,如果读了博,肯定是不会问了,还好我是拿旧的屏幕,如果新的估计肯定被换掉了。

今天看到陈立人公布了答案,还是用堆来做的,但是不是之前想的最大堆,而是最小堆,同时维护一个最大值,这样保证每次都知道当前堆中的最大值。
算法中维护这个词是很微妙的,我不是很习惯用,导致经常想到遍历一遍当前找最大,其实完全没必要。比较当前堆顶和当前最大值大小,便可以知道是否是交集了,
如果最小的等于最大值,那整个堆都是同一元素,否则需要逐个出堆直到遇到堆顶等于最大值(不可能大于)。但是似乎不需要存储

struct ListNode
{
    int val;
    ListNode* next;
    ListNode(int x): val(x), next(NULL)
    {
    }
};

bool comp(ListNode* p1,ListNode*p2)
{
    return p1->val>p2->val;
}
bool AtLeastOnePointNULL()
{
    for(int i=0;i<(int)p.size();i++)
        if(p[i]==NULL)
            return true;
    return false;
}

ListNode* Intersection(vector<ListNode* > ListHead)
{
    int max=0x80000000;
    //0x7FFFFFFF;
    vector<ListHead* > p;
    if(ListHead.size()==0)
        return NULL;
    for(int i=0;i<ListHead.size();i++)
    {
        p.push_back(ListHead[i]);
        if(max<ListHead[i]->val)
            max=ListHead[i]->val;
    }
    make_heap(p.begin(),p.end(),comp);
    ListNode* head=NULL, tail;
    while(1)
    {
        if(AtLeastOnePointNULL())
            break;
        if(p[0]->val<max)
        {
            while(p[0]->val<max)
            {
                pop_heap(p.begin(),p.end());
                ListNode* pnext=p[p.size()-1]->next;
                if(pnext==NULL)
                    return head;
                if(max<pnext->val)
                    max=pnext->val;
                p.pop_back();
                p.push_back(pnext);
                push_heap(p.begin(),p.end());
            }
        }
        else
        {
            if(head==NULL)
            {
                head=new ListNode(p[0]->val);//at least one ele in heap
                tail=head;
            }
            else
            {
                tail->next=new ListNode(p[0]->val);
                tail=tail->next;
            }
            for(int i=0;i<p.size();i++)
            {
                p[i]=p[i]->next;
                if(p[i]->val>max)
                    max=p[i]->val;
            }
            make_heap(p.begin(),p.end(),comp);
        }
    }
    return head;
}

Posted by richard爱闹 - 8月 23 2014
如需转载,请注明: 本文来自 Richard