致我们终将忘记的算法(不分你我的查找和排序)

1->合并两个有序数组

void Merge(int A[],int m,int B[],int n){

    int ia=m-1,ib=n-1,icur=m+n-1;

    while(ia>=0 && ib>=0){

          A[icur--]=A[ia]>=B[ib]?A[ia--]:B[ib--];

    }

    while(ib>=0){A[icur--]=B[ib--];}

}

2->合并两个有序的链表

ListNode *mergeTwoLists(ListNode *l1,ListNode* l2){

    if(l1==NULL) return l2;

    if(l2==NULL)  return l1;

    ListNode dummy(-1);       //辅助链表头结点

    ListNode* p=&dummy;

    for(;l1!=NULL&&l2!=NULL;p=p->next){

         if(l1->val>l2->val){p->next=l2; l2=l2->next;}

         else{p->next=l1; l1=l1->next;}

    }

    p->next=l1!=NULL?l1:l2;

    return dummy.next;

}

3->合并K个已经排序好的链表

解题方法:先写出合并两个链表的程序,用循环逐个合并两个链表

ListNode *mergeTwoLists(ListNode* l1,ListNode *l2){

    ListNode head(-1);     //辅助头结点

    ListNode* p=&head;

    for(;l1!=NULL &&l2!=NULL;p=p=>next){

        if(l1>val<l2->val){p->next=l1; l1=l1->next;}

        else {p->next=l2;l2=l2->next;}

    }

    p->next=l1!=NULL?l1:l2;

    return head->next;

}

ListNode *mergeKLists(vector<ListNode *> &lists){

    if(lists.size()==0)    return NULL;

    ListNode *p=lists[0];

    for(int i=1;i<lists.size();i++){

         p=mergeTwoLists(p.lists[i]);

    }

    return p;

}

4->采用插入法排序一个链表

解题方法:插入法排序,基本思想选取一个结点,找到要插入的位置,将结点插入即可

ListNode* findInsertPos(ListNode *head,int x){          //查找要插入的位置的前一个结点

    ListNode *pre=NULL;

    for(ListNode* cur=head;cur!=NULL;cur=cur->next){

       if(cur->val<=x) {pre=cur; continue;}

       else break;

    }

    retun pre;

}

ListNode *insertionSortList(ListNode* head){

    ListNode dummy(INT_MIN);     //辅助头结点

    for(ListNode *cur=head;cur!=NULL;){

        ListNode *pre=findInsertPos(dummy,cur-val);

        ListNode *tmp=cur->next;

        cur->next=pre->next;  pre->next=cur;  cur=tmp;

    }

    return dummy.next;

}

6->在O(nlogn)的时间内排序一个链表

解题方法:这一可以用归并算法实现,假若链表是双向链表则可以采用快排的实现方式

ListNode *mergeTwoLists(ListNode* l1,ListNode *l2){

    ListNode dummy(-1);

    ListNode*p=&dummy;

    for(;l1!=NULL &&l2!=NULL;p=p->next){

         if(l1->val<l2->val){p->next=l1; l1=l1->next;}

         else{p->next=l2;l2=l2->next;}

    }

    p->next=l1!=NULL?l1:l2;

    return dummy.next;

}

ListNode* sortList(ListNode *head){

    if(head==NULL ||head->next==NULL)  return head;  //只有一个结点或者是空链表就没有必要排序

    ListNode *fast=head,*slow=head;  //两个指针,作用将链表分成两段再进行归并

    while(fast->next!=NULL && fast->next->next!=NULL){

          fast=fast->next->next;  slow=slow->next;                        //fast指针遍历的速度是slow指针的两倍,所以当fast指针达到链表尾巴的时候,slow达到链表的中部

    } 

    fast=slow;  slow=slow->next; fast->next=NULL;  //将链表从中间断开

    ListNode *l1=sortList(head); ListNode *l2=sortList(slow);

   return mergeTwoLists(l1,l2);

}

6->在O(n)的时间内找到一个无序数组的第一个缺失的数值

解题方法:要找到连续数列的第一个断点,正常的思想是先排序,然后遍历数组,然而常见的排序算法快排的时间复杂度较低,需要O(nlogn)不符合题目的要求,又由于题目中主要涉及整数,所以可以采用桶排序算法

7->一个数组中只包含0,1,2三个数字,要求O(n)将这个数组排序

解题方法:计数排序

void sortColors(int A[],int n){

    int count[3]={0};

    for(int i=0;i<n;i++)  count[A[i]]++;

    for(int i=0,index=0;i<3;i++)

         for(int j=0;j<count[i];j++)   A[index++]=i;

}

8->在O(logn)的时间内在一个已经排序的数组内找出给定值的开始和结束位置,该值在数组中可能出现不只一次

解题方法:已经排序好了,那么用二分查找就可以使时间复杂度达到O(logn),先采用2分查找定位到目标数值,然后用左右扩展的方式找到起始和结束的位置

vector<int>  searchRange(int A[],int n,int target){

    int low=0,high=n-1;

    vector<int> ret;

    while(low<=high){

         int mid=(low+high)/2;

         if(A[mid]==target) {low=mid; break;}

         if(A[mid]>target) high=mid-1;

         else low=mid+1;

    } 

    if(low>high)   {ret.push_back(-1);ret.push_back(-1); return ret;}

   high=low;

   while(low>=0&& high<n&&(A[low]==target || A[high]==target)){

       if(A[low-1]==target) low--;

       if(A[high+1]==target) high++;

   }

   ret.push_back(low+1,high-1); return ret;

}

10->一个已经排序的数组,一个目标数组若存在这个数组中,返回在数组中的位置,否则返回应该插入的位置

int lower_bound(int A[],int n,int target){     //二分查找,若吧存在则返回应当插入的

   int low=0,,high=n;

   while(low!=high){

        int mid=(low+high)/2;

        if(target>A[mid]) low=mid+1;

        else high=mid;

   }

   return low;

}

发布了99 篇原创文章 · 获赞 8 · 访问量 4万+

猜你喜欢

转载自blog.csdn.net/CodeAsWind/article/details/39210417
今日推荐