力扣面试题——链表与栈部分

找出数组中重复的数字。


在一个长度为 n 的数组 nums 里的所有数字都在 0~n-1 的范围内。数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次。请找出数组中任意一个重复的数字。

void Swap(int*a,int*b)
{
int c=*a;
*a=*b;
*b=c;
}
//利用快速排序
// //单趟排序   左右指针法
// int PartSort(int *a,int begin,int end)
// {
//     int key=a[end];
//     int tmp=end;
//     while(begin<end){
//         while(begin<end&&a[begin]<=key)
//             begin++;
//         while(begin<end&&a[end]>=key)
//             end--;
//        Swap(&a[begin],&a[end]);
//     }   
//     Swap(&a[begin],&a[tmp]);
//     return begin;
// }
// //单趟排序 挖坑法
// int PartSort(int *a,int begin,int end)
// {
//     int key=a[end];//坑
//     while(begin<end)
//     {
//         while(begin<end&&a[begin]<=key)//右边找大
//         begin++;
//         a[end]=a[begin];//找到打的扔到右边的坑里去,同时begin形成新的坑位
//         while(begin<end&&a[end]>=key)//左边找小
//         end--;
//         a[begin]=a[end];//找到小的扔到左边的坑位中去,同时end形成新的坑
//     }
//         a[begin]=key;
//         return begin;
// }
// //单趟排序 前后指针法
// int PartSort(int *a,int begin,int end)
// {
// //设定 cur end 与prev    
// //cur指向开始,prev指向开始的前一个数字。end指向最后一个数字!
// //cur向后移动,遇到大于end位置的数字,prev++。当cur=prev不做反应。否则狡猾cur位置与prev位置的数字
// //当cur==end;++prev 交换prev位置与end位置的数字
//     int cur=begin;
//     int key=a[end];
//     int prev=begin-1;
//     while(cur<end){
//         if(a[cur]>key&&++prev!=cur)//当第一个条件为假的时候便不会执行第二个条件,prev也就不会++;
//             Swap(&a[prev],&a[cur]);
//         ++cur;
//     }
//     ++prev;
//     Swap(&a[prev],&a[end]);
//     return  prev;
// }
// void QuickSort(int *a,int begin,int end)
// {
//     if(begin>=end)
//         return;
//     int keyindex=PartSort(a,begin,end);
//     QuickSort(a,begin,keyindex-1);
//     QuickSort(a,keyindex+1,end);
// }


int findRepeatNumber(int* nums, int numsSize){
//   //进行直接插入排序
//   //而后比较连续的数字即可
//哈希排序
    int gap=numsSize;
    while(gap>1){
        gap=gap/3+1;
    for(int i=0;i<numsSize-gap;i++)
    {
        int end=i;
        int tmp=nums[end+gap];
        while(end>=0){
            if(nums[end]>tmp){
                nums[end+gap]=nums[end];
                end-=gap;
            }
            else
            break;
        }
    nums[end+gap]=tmp;
    }
}
    // //选择排序
    // int begin=0;
    // int end=numsSize-1;
    // while(begin<end)
    // {
    //     int mini=begin;
    //     int maxi=end;
    //     for(int i=0;i<=end;i++){
    //         if(nums[i]<nums[mini])
    //             mini=i;
    //         if(nums[i]>nums[maxi])
    //             maxi=i;
    //     }
    //     Swap(&nums[begin],&nums[mini]);
    //     if(begin==maxi)
    //         maxi=mini;
    //     Swap(&nums[end],&nums[maxi]);
    //     begin++;
    //     end--;
    // }
    // //冒泡排序
    // for(int end=numsSize-1;end>0;end--){
    //     for(int i=0;i<end;i++){
    //         if(nums[i]>nums[i+1])
    //             swap(&nums[i],&nums[i+1]);
    //     }
    // }
  
  //  QuickSort(nums,0,numsSize-1);
    for(int i=0;i<numsSize;i++)
    {
        if(nums[i]==nums[i+1])
            return nums[i];
    }
    return -1;
}

请实现一个函数,把字符串 s 中的每个空格替换成"%20"。

class Solution {
public:
    string replaceSpace(string s) {
       string linjia;
       for(auto c:s)
       {
           if(c==' ')
           {
               linjia.push_back('%');
               linjia.push_back('2');
               linjia.push_back('0');
           }
           else
           {
               linjia.push_back(c);
           }
       }
       return linjia;
}
};

输入一个链表的头节点,从尾到头反过来返回每个节点的值(用数组返回)。

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    vector<int> reversePrint(ListNode* head) {
    vector<int>res;
    for(ListNode* i=head;i!=NULL;i=i->next)
        res.push_back(i->val);
    reverse(res.begin(),res.end());
   return res;
   }
};
//         vector<int>res;
//         if(head==NULL){
//         res.push_back(NULL);
//         return res;}
//         else if(head->next==NULL){
//         res.push_back(head->val);
//         return  res;}
//         ListNode *p1=head,*p2=NULL,*p3=p1->next;
//         while(p1){
//         p1->next=p2;
//         p2=p1;
//         p1=p3;
//         if(p3)
//         p3=p3->next;
//         }
//         while(p2){
//             res.push_back(p2->val);
//             p2=p2->next;
//         }
//         return res;
//     }
// };

用两个栈实现一个队列。队列的声明如下,请实现它的两个函数 appendTail 和 deleteHead ,分别完成在队列尾部插入整数和在队列头部删除整数的功能。(若队列中没有元素,deleteHead 操作返回 -1 )

class CQueue {
public:
    stack<int>a;
    stack<int>b;
    CQueue() {

    }
    
    void appendTail(int value) {
        a.push(value);
    }
    
    int deleteHead() {
        if(a.empty()&&b.empty())
        return -1;
        if(b.empty()&&!a.empty())
        {
            while(!a.empty())
            {
                b.push(a.top());
                a.pop();
            }
        }
        int cur=b.top();
        b.pop();
        return cur;
    }
};

/**
 * Your CQueue object will be instantiated and called as such:
 * CQueue* obj = new CQueue();
 * obj->appendTail(value);
 * int param_2 = obj->deleteHead();
 */

给定单向链表的头指针和一个要删除的节点的值,定义一个函数删除该节点。

返回删除后的链表的头节点。

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */


struct ListNode* deleteNode(struct ListNode* head, int val){
    struct ListNode* cur=head->next;
    struct ListNode* prev=head;
    if(head==NULL)
    return;
    if(head->next==NULL)
    return;
    if(head->val==val)
        return head->next;
    else{
        while(cur->val!=val){
            cur=cur->next;
            prev=prev->next;
        }
        prev->next=cur->next;
        return head;
    }
   
    // while(cur){
    //     if(cur->val==val)
    //     break;
    //     prev=cur;
    //     cur=cur->next;
    // }
    // if(cur==head){//处理删除节点在头部的情况
    //     head=cur->next;
    // }
    // if(cur->next==NULL){//处理删除节点在尾部的情况
    // prev->next=NULL;
    // }
    // else{
    // prev->next=cur->next;
    // }
    // return head;
}

输入一个链表,输出该链表中倒数第k个节点。为了符合大多数人的习惯,本题从1开始计数,即链表的尾节点是倒数第1个节点。例如,一个链表有6个节点,从头节点开始,它们的值依次是1、2、3、4、5、6。这个链表的倒数第3个节点是值为4的节点

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */

typedef struct ListNode Node;
struct ListNode* getKthFromEnd(struct ListNode* head, int k){
    if(head==NULL||head->next==NULL)
    {
        return head;
    }
    Node *cur=head;
    Node *prev=NULL;
    Node *p=cur->next;
    while(cur)
    {
        cur->next=prev;
        prev=cur;
        cur=p;
        if(p)
        p=p->next;
    }
    Node *r=prev;
    while(k-1){
        prev=prev->next; 
        k--;
    }
    prev->next=NULL;
    Node *p1=r;
    Node *p2=NULL;
    Node *p3=r->next;
    while(p1)
    {
        p1->next=p2;
        p2=p1;
        p1=p3;
        if(p3)
        p3=p3->next;
    }
    return p2;
}

定义一个函数,输入一个链表的头节点,反转该链表并输出反转后链表的头节点。

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */


struct ListNode* reverseList(struct ListNode* head){
    if(head==0||head->next==0)
    return head;
    struct ListNode*prev=NULL;
    struct ListNode *cur=head;
    struct ListNode *p=cur->next;
    while(cur){
        cur->next=prev;
        prev=cur;
        cur=p;
        if(p)
        p=p->next;
    }
    return prev;
}

输入两个递增排序的链表,合并这两个链表并使新链表中的节点仍然是递增排序的。

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */


struct ListNode* mergeTwoLists(struct ListNode* l1, struct ListNode* l2){
    struct ListNode* head=NULL;
    struct ListNode* lite=NULL;
    if(l1==NULL)//开始就判空
    return l2;
    if(l2==NULL)
    return l1;
    while(l1&&l2)
    {
        if(l1->val<l2->val)
        {
            if(lite==NULL)
            {
                head=lite=l1;
            }
            else{
            lite->next=l1;
            lite=l1;
            }
            l1=l1->next;
        }
        else
        {
            if(lite==NULL)
            {
                head=lite=l2;
            }
            else{
            lite->next=l2;
            lite=l2;
            }
            l2=l2->next;
        }
    }
    if(l1)
    {
        lite->next=l1;
    }
    else if(l2)
    {
        lite->next=l2;
    }
    return head;
}

定义栈的数据结构,请在该类型中实现一个能够得到栈的最小元素的 min 函数在该栈中,调用 min、push 及 pop 的时间复杂度都是 O(1)。

class MinStack {
public:
    stack<int>a;
    stack<int>b;//这是一个辅助栈
    /** initialize your data structure here. */
    MinStack() {

    }
    
    void push(int x) {
        a.push(x);
        if(b.empty()||b.top()>=x)
        b.push(x);
    }
    
    void pop() {
        if(a.top()==b.top())
        b.pop();
        a.pop();
    }
    
    int top() {
        return a.top();
    }
    
    int min() {
        return b.top();
    }
};

/**
 * Your MinStack object will be instantiated and called as such:
 * MinStack* obj = new MinStack();
 * obj->push(x);
 * obj->pop();
 * int param_3 = obj->top();
 * int param_4 = obj->min();
 */

输入两个链表,找出它们的第一个公共节点。

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
        if(headA==NULL||headB==NULL)
        return NULL;
        ListNode* cur=headA;
        ListNode* pur=headB;
        while(cur!=pur)
        {
            cur=cur==NULL?headB:cur->next;
            pur=pur==NULL?headA:pur->next;
        }
        return cur;
    }
};

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值