链表(2)

一、对于一个链表,我们需要用一个特定阈值完成对它的分化,使得小于等于这个值的结点移到前面,大于该值的结点在后面,同时保证两类结点内部的位置关系不变。
给定一个链表的头结点head,同时给定阈值val,请返回一个链表,使小于等于它的结点在前,大于等于它的在后,保证结点值不重复。
测试样例:
{1,4,2,5},3
{1,2,4,5}

struct ListNode {
    int val;
    struct ListNode *next;
    ListNode(int x) : val(x), next(NULL) {}
};
class Divide {
public:
    ListNode* listDivide(ListNode* head, int val) {
        ListNode small(0);
        ListNode large(0);
        ListNode *p=head;
        ListNode *psmall=&small,*plarge=&large; 
        while(p){
            if(p->val>val){
                plarge->next=p;

                plarge=plarge->next;
            }
            else{
                psmall->next=p;

                psmall=psmall->next;
            }
            p=p->next;
        }
        psmall->next=large.next;
        plarge->next=NULL;
        return small.next;
    }
};

二、现有两个升序链表,且链表中均无重复元素。请设计一个高效的算法,打印两个链表的公共值部分。
给定两个链表的头指针headA和headB,请返回一个vector,元素为两个链表的公共部分。请保证返回数组的升序。两个链表的元素个数均小于等于500。保证一定有公共值
测试样例:
{1,2,3,4,5,6,7},{2,4,6,8,10}
返回:[2,4,6]

class Common {
public:
    vector<int> findCommonParts(ListNode* headA, ListNode* headB) {
        vector<int> result;
        ListNode* LA = headA;
        ListNode* LB = headB;
        //如果两个链表有任意一个为空,则直接返回
        if(LA==NULL||LB==NULL) 
            return result;
        //链表均不为空时
        while(LA != NULL && LB != NULL){
            if(LA->val == LB->val){
                     result.push_back(LA->val);
                    LA = LA->next;
                    LB = LB->next;
                }
            else if(LA->val > LB->val){
                LB = LB->next;
            }
            else
                LA = LA->next;
        }
        return result;
    }
};

三、有一个单链表,请设计一个算法,使得每K个节点之间逆序,如果最后不够K个节点一组,则不调整最后几个节点。例如链表1->2->3->4->5->6->7->8->null,K=3这个例子。调整后为,3->2->1->6->5->4->7->8->null。因为K==3,所以每三个节点之间逆序,但其中的7,8不调整,因为只有两个节点不够一组。
给定一个单链表的头指针head,同时给定K值,返回逆序后的链表的头指针。

class KInverse {
public:
    ListNode* inverse(ListNode* head, int k) {
        if(head==NULL||head->next==NULL||k<2) 
            return head;
        ListNode *p=head;
        int n=0;    //n为链表中结点的个数
        while(p){
            n++;       
            p=p->next;
        }
        ListNode *node=new ListNode(0);
        node->next=head;
        ListNode *pre=node,*cur=head,*temp=cur->next;
        for(int i=0;i<n/k;i++){           //i为需要逆序的子链表的个数       
            for(int j=1;j<k;j++){         //链表中k个结点逆序
                cur->next=temp->next;
                temp->next=pre->next;
                pre->next=temp;
                temp=cur->next;
            }
            if(temp&&temp->next){
            pre=cur;
            cur=temp;
            temp=cur->next;
            }
            else 
                break;
        }
        return node->next;
    }
};

附:单链表逆序

这里写图片描述

这里写图片描述

从图(1)到图(2)的伪代码如下:

p->next = prev;   //当前结点指向前驱结点
prev = p;         //后移
p = latter;
latter = p->next;

这里写图片描述

这里写图片描述

template<class T>
void List<T>::Inverse()                
{
    if(first == NULL)    return;
    LinkNode<T> *p, *prev, *latter;    
    p = first->next;         // 当前结点
    prev = NULL;             // 前一结点
    latter = p->next;         // 下一结点
    while(p != NULL)
    {
        p->next = prev;        // 当前结点指针指向前一结点
        prev = p;              // 后移
        p = latter;
        if(p != NULL)          // 如果p指针是NULL,已经满足终止条件
            latter = p->next;
    }
    first->next = prev;;       // 最后连上附加头结点
}

四、现在有一个单链表。链表中每个节点保存一个整数,再给定一个值val,把所有等于val的节点删掉。
给定一个单链表的头结点head,同时给定一个值val,请返回清除后的链表的头结点,保证链表中有不等于该值的其它值。请保证其他元素的相对顺序。
测试样例:
{1,2,3,4,3,2,1},2
{1,3,4,3,1}

class ClearValue {
public:
    ListNode* clear(ListNode* head, int val) 
    {
        if(head==NULL)
            return head;
        ListNode *pointer=head;
        ListNode newHead(0);
        ListNode *nHead=&newHead;
        while(pointer!=NULL)
        {
            if(pointer->val!=val)    //保留与val值不一样的结点
            {
                nHead->next=pointer;
                nHead=nHead->next;   
            }
            pointer=pointer->next;
        }
        nHead->next=NULL;
        return newHead.next;
    }
};

五、请编写一个函数,检查链表是否为回文。
给定一个链表ListNode* pHead,请返回一个bool,代表链表是否为回文。
测试样例:
{1,2,3,2,1}
返回:true
{1,2,3,2,3}
返回:false

class Palindrome {
public:
    bool isPalindrome(ListNode* pHead) {
        stack<int> s;     
        ListNode *p1=pHead,*p2=pHead;
        while(p1){           //将链表中的数据域压入栈中
            s.push(p1->val);
            p1=p1->next;
        }
        //如果栈中弹出的数据完全等于链表中的数据域,则表示为回文
        while(p2){           
            if(p2->val==s.top()){
                p2=p2->next;
                s.pop();
            }
            else
                return false;
        }
        return true;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值