题解 | #单链表的排序#

单链表的排序

https://www.nowcoder.com/practice/f23604257af94d939848729b1a5cda08

链表的排序和普通的排序唯一的区别应该在于需要重新创建新的链表?因为创建新的链表在思路上比较简单~

我们还是先得到链表的长度,从而定义链表长度大小的数组,将链表中的val存储进数组,然后对于数组进行一个归并排序的处理,最后创建一个新的链表即可。

思路过于复杂了qaq,有看到的大佬可以分享一下更为简便的方法吗~awa

void merge(int arr[],int left,int mid,int right)
{
    int len1 = mid - left+1;//3
    int len2 = right - mid;//2//0 1 2 3 4
    int arr1[len1];
    int arr2[len2];
    for(int i=0;i<len1;i++)
    {
        arr1[i] = arr[left+i];
    }
    for(int i=0;i<len2;i++)
    {
        arr2[i] = arr[mid+1+i];
    }
    int out[right-left+1];
    int pos = 0;
    int pos1=0;
    int pos2=0;
    while(pos1<len1&&pos2<len2)
    {
        if(arr1[pos1]<arr2[pos2])
        {
            out[pos] = arr1[pos1];
            pos1++;
        }
        else if(arr1[pos1]>=arr2[pos2])
        {
            out[pos] = arr2[pos2];
            pos2++;
        }
        pos++;
    }
    while(pos1<len1)
    {
        out[pos] = arr1[pos1];
        pos1++;
        pos++;
    }
    while(pos2<len2)
    {
        out[pos] = arr2[pos2];
        pos2++;
        pos++;
    }
    for(int i=0;i<right-left+1;i++)
    {
        arr[left+i] = out[i];
    }
}
void mergesort(int arr[],int left,int right)
{
    if(left>=right)
    {
        return;
    }
    int mid = (left + right)/2;
    mergesort(arr, left, mid);
    mergesort(arr, mid+1,right);
    merge(arr,left,mid,right);
}
int getlen(struct ListNode* head)
{
    int cnt = 0;
    while(head!=NULL)
    {
        cnt++;
        head = head->next;
    }
    return cnt;
}
struct ListNode* createnode(int val)
{
    struct ListNode* node = (struct ListNode*)malloc(sizeof(struct ListNode));
    if(node!=NULL)
    {
        node->next = NULL;
        node->val = val;
        return node;
    }
    return NULL;
}
struct ListNode* sortInList(struct ListNode* head ) {
    // write code her
    int len = getlen(head);
    if(len==0)
    {
        return NULL;
    }
    int arr[len];
    for(int i=0;i<len;i++)
    {
        if(head!=NULL)
        {
            arr[i] = head->val;
            head =head ->next;
        }
        else 
        {
            printf("...some error\n");
        }
    }
    mergesort(arr,0,len-1);
    struct ListNode* newhead = createnode(arr[0]);
    struct ListNode* output = newhead;
    for(int i=1;i<len;i++)
    {
        struct ListNode* newnode = createnode(arr[i]);
        if(newnode!=NULL)
        {
            newhead->next = newnode;
            newhead = newhead->next;
        }
    }
    return output;
}

全部评论

相关推荐

点赞 评论 收藏
分享
会飞的猿:我看你想进大厂,我给你总结一下学习路线吧,java语言方面常规八股要熟,那些java的集合,重点背hashmap八股吧,jvm类加载机制,运行时分区,垃圾回收算法,垃圾回收器CMS、G1这些,各种乐观锁悲观锁,线程安全,threadlocal这些。在进阶一些的比如jvm参数,内存溢出泄漏排查,jvm调优。我这里说的只是冰山一角,详细八股可以去网上找,这不用去买,都免费资源。mysql、redis可以去看小林coding,我看你简历上写了,你一定要熟,什么底层b+树、索引结构、innodb、mvcc、undo log、redo log、行级锁表级锁,这些东西高频出现,如果面试官问我这些我都能笑出来。消息队列rabbitmq也好kafka也好,学一种就行,什么分区啊副本啊确认机制啊怎么保证不重复消费、怎么保证消息不丢失这些基本的一定要会,进阶一点的比如LEO、高水位线、kafka和rocketmq底层零拷贝的区别等等。计算机网络和操作系统既然你是科班应该理解起来问题不大,去看小林coding这两块吧,深度够了。spring boot的八股好好看看吧,一般字节腾讯不这么问,其他的java大厂挺爱问的,什么循环依赖啥的去网上看看。数据结构的话科班应该问题不大,多去力扣集中突击刷题吧。项目的话其实说白了还是结合八股来,想一想你写的这些技术会给你挖什么坑。除此之外,还有场景题、rpc、设计模式、linux命令、ddd等。不会的就别往简历上写了,虽然技术栈很多的话好看些,但背起来确实累。总结一下,多去实习吧,多跳槽,直到跳到一个不错的中厂做跳板,这是一条可行的进大厂的路线。另外,只想找个小厂的工作的话,没必要全都照这些准备,太累了,重点放在框架的使用和一些基础八股吧。大致路线就这样,没啥太多难度,就是量大,你能达到什么高度取决于你对自己多狠,祝好。
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务