时间复杂度

计算机在1s、2s内可运行<=10^8次

 

前为给定的大小,后均为时间复杂度↓

n <= 30,指数级别:考虑 dfs+剪枝

n = 100 => n^3:floyd算法

n = 1000 => n^2:n^2logn,地杰斯特拉算法

n = 10000 => n * sqrt(n):块状链表

n = 100000 => nlogn:排序算法、线段树、树状数组、set/map、heap、heap+dijkstra、spfa、求凸包、求半平面交、二分

n = 1000000 => O(n)、nlogn:hash、双指针扫描、kmp、AC自动机,

                                                  常数比较小的nlogn算法:排序、树状数组、heap、dijkstra、spfa

n = 10000000 => O(n):双指针扫描、kmp、AC自动机、线性筛数组

n = 10^9 => O(sqrt(n))

n = 10^18 =>O(logn):求最大公约数、

 

链表专题

题目1:给定一个有序链表,要求删除链表中的重复元素,使得原链表的元素仅出现一次。

链表结点的定义如下:

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

样例1:1->1->2,则输出为1->2

样例2:1->1->2->3->3,则输出1->2->3

算法:线性扫描  O(n),从前往后扫描整个链表,如果一个结点和其后继结点相同,则直接删除后继结点,否则指针移动到后继结点。

class Solution{
public:
    ListNode* deleteDuplicates(ListNode* head){
        if(!head) return nullptr;
        ListNode *p = head;
        while(p->next){
            if(p->next->val == p->val) p->next = p->next->next;
            else p = p->next;
        }
        return head;
    }
}

题目2:给出两个排好序的单向链表,返回合并排序后新的单向链表。

样例:1->2->4,1->3->4

返回:1->1->2->3->4->4

算法:线性合并   O(n)

class Solution{
public:
    ListNode* mergeTwoLists(ListNode* l1,ListNode *l2){
        ListNode *dummy = new ListNode(0);
        ListNode *cur = dummy;
        while(l1!=NULL && l2!=NULL){
            if(l1->val < l2->val){
                cur->next = l1;
                l1 = l1->next;
            }
            else{
                cur->next = l2;
                l2 = l2->next;
            }
            cur = cur->next;
        }
        cur->next = (l1!=NULL?l1:l2);
        return dummy->next;
    }
}

题目3:给定一个链表,如果存在环,则返回环的入口,否则返回null。注:不能修改链表。是否只是用额外O(1)的空间?

算法:指针扫描 O(n),构造两个指针first和second,first每走一步,second走两步,如果过程中,second走到null,则不存在环,否则当first和second相遇时,让first返回起点,second待在相遇点不动,然后两指针每次分别走一步,当相遇时,该点就是环的入口。

class Solution {
public:
    ListNode *detectCycle(ListNode *head) {
        ListNode *fast,*slow;
        fast = slow = head;
        while(fast!=nullptr && fast->next!=nullptr){
            fast = fast->next->next;
            slow = slow->next;
            if(slow == fast){
                ListNode *node1 = head;
                ListNode *node2 = fast;
                while(node1!=node2){
                    node1 = node1->next;
                    node2 = node2->next;
                }
                return node1;
            }
        }
        return NULL;
    }
};

题目4:给定一个单链表,请使用O(nlogn)的时间复杂度和额外O(1)的空间复杂度对其进行排序。

样例1:

输入:4->2->1->3

输出:1->2->3->4

样例2:

输入:-1->5->3->4->0

输出:-1->0->3->4->5

算法:归并排序,时间O(nlogn),自顶向下递归形式的归并排序,由于递归需要使用系统栈,递归最大深度为logn,所以需要额外O(logn)的空间。所以我们需要使用自底向上非递归形式的归并排序算法。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值