算法练习

来源:互联网 发布:程序员工作心得体会 编辑:程序博客网 时间:2024/05/16 05:16

算法练习 - 排序


练习1 LeetCode - 524. Longest Word in Dictionary through Deleting

class Solution(object):    # 对链表排序    # 时间复杂度要求:O(nlogn)    # 空间:常量空间    # 数据结构:链表    # 排序算法:归并    def sortList(self, head):        """        :type head: ListNode        :rtype: ListNode        """    # 子程序 ifcanbeformed:判断 str_o 是否可以通过删除一些字符来得到 str_n    # 输入:str_o,str_n    # 返回:true,false    def ifcanbeformed(self,str_o,str_n):    # 设 str_n_index = 0        str_n_index = 0    # 遍历 str_o,标识i:        for i in range(len(str_o)):    #     如果 str_o[i] == str_n[str_n_index]:            if str_o[i] == str_n[str_n_index]:    #         str_n_index++                str_n_index+=1    #     如果str_n_index == str_n.length:            if str_n_index == len(str_n):    #         返回 true                return True    # 返回false        return False    # 子程序 lexOrderMaxString(s1,s2):    # 输入:两个相等长度的字符串    # 返回: 其中字典序排列较大的那个    def lexOrderMaxString(self,s1,s2):        # 遍历 i to s1.length:        for i in range(len(s1)):        #     如果s1[i] > s2[i]:            if s1[i] < s2[i]:        #         那么返回s1                return s1        #     如果s1[i] < s2[i]:            if s1[i] > s2[i]:        #         那么返回s2                return s2        # 遍历完都一样,返回 s1            return s1    # 子程序 findLongestWord:     # 输入:字符串s 字符集合d    # 返回:d中最长的,可以通过s删除一些字符串得到的那个字符串    def findLongestWord(self,s,d):        # max_length = MIN        max_length = -sys.maxsize - 1        # max_str = 空字符串        max_str = ''        # 遍历d,string:        for string in d:        #     如果 判断当前的可以formed:            if self.ifcanbeformed(s,string):        #         如果 max_length < str.length:                if max_length < len(string):        #             max_length = str.length                    max_length = len(string)        #             max_str = str                    max_str = string        #       如果 长度相当,则要根据字典序来判断                if max_length == len(string):                    max_str = self.lexOrderMaxString(max_str,string)        # 返回str        return max_str

练习2 LeetCode - 75. Sort Colors

    # 输入:一个数组,只包含0,1,2三个数    # 返回:排好序的数组    # 要求,计数排序,本地    def sortColors(self, nums):        """        :type nums: List[int]        :rtype: void Do not return anything, modify nums in-place instead.        """        count = [0,0,0]        for i in nums:            if i == 0:                count[0]+=1            elif i == 1:                count[1]+=1            elif i == 2:                count[2]+=1        index = 0        for c in range(len(count)):            if c == 0:                for j in range(count[c]):                    nums[index] = 0                    index+=1            elif c == 1:                for j in range(count[c]):                    nums[index] = 1                    index+=1            elif c == 2:                for j in range(count[c]):                    nums[index] = 2                    index+=1

练习3 LeetCode - 274. H-Index

class Solution(object):    # 一个科学家发布了一组论文,论文的文献引用数为[3,0,6,1,5]    # h-index的定义是有h篇论文至少有h个引用,其余的论文的引用数都小于h篇    # 输入:citations 表示这组论文的引用数    # 输出:h-index(如果有多个index,那么输出最大的那个)    def hIndex(self, citations):        # 使用快排对数组进行原地降序排序 O(nlgn)        citations = sorted(citations,reverse=True)        # sums 表示对应论文比它大的论文数有多少个,长度和citations相同        sums = [0]*len(citations)        # h_index为 0        h_index = 0        # 遍历 citations,指标为i:        for i in range(len(citations)):        #     如果 i 为 0:            if i == 0:        #         sums[i] = i                sums[i] = 1        #     否则:            else:        #         sums[i] = sums[i-1]+1                sums[i] = sums[i-1]+1        #     如果 sums[i] >= citations[i]:            if sums[i] <= citations[i]:        #         如果 h_jndex < citations[i]:                if h_index < sums[i]:        #             h_jndex = citations[i]                    h_index = sums[i]        # 返回 h_index        return h_index

练习4 LeetCode - 147. Insertion Sort List

以下是通过操作节点来实现插入排序的,但是对应最大的测试用例超时了

class Solution(object):    # 使用插入排序来岁链表进行排序    # 输入:head 表头    # 输入:排序后的表头    def insertionSortList(self, head):        # 如果head为空,或者为1,那么直接返回        if head == None:            return None        if head.next == None:            return head        # node2 = head.next,head和之后分离        node2 = head.next        head.next = None        # 当 node2 不为空,则循环:        while node2 != None:        #     tempnode2指向node2,node2向后移动            tempnode2 = node2            node2 = node2.next        #     设 node1 为 head            node1 = head        #     当 node1 不为空,则循环:            while node1 != None:        #         tempnode1  = node1                tempnode1 = node1        #         node1 = node1.next                node1 = node1.next        #         判断tempnode1和tempnode2的值,一共有4种情况需要插入:        #         头之前,中间,尾巴,或者不插        #         插入的3种情况        #         1. 如果 tempnode1 == head,且 tempnode1 大于 tempnode2,tempnode2要插在tempnode1之前:                if (tempnode1.val==head.val)and(tempnode1.val>tempnode2.val):                    tempnode2.next = tempnode1                    head = tempnode2                    break        #         2. 如果tempnode1 小于 tempnode2,且tempnode1已经是链表的最后一个,tempnode2直接插入tempnode1之后                elif (tempnode1.val <= tempnode2.val)and(tempnode1.next == None):                    tempnode1.next = tempnode2                    tempnode2.next = None                    break        #         3. 如果tempnode1 小于 tempnode2,且tempnode1.next大于tempnode2,tempnode2插在tempnode1和tempnode1.next之间                elif (tempnode1.val <= tempnode2.val)and(tempnode1.next.val > tempnode2.val):                    tempnode2.next = tempnode1.next                    tempnode1.next = tempnode2                    break        # 返回head        return head

其实也可以直接对node中值进行置换

class Solution(object):    # 使用插入排序来岁链表进行排序    # 输入:head 表头    # 输入:排序后的表头    def insertionSortList(self, head):        # 如果head为空,或者为1,那么直接返回        if head == None:            return None        if head.next == None:            return head        # 设node为head的下一个        node = head.next        # 如果node不为空,则循环        while node != None:        #     val 为 node的值            val = node.val        #     设node2为head            node2 = head        #     如果 node2 != node 循环:            while node2 != node:        #         如果node<node2,则:                if val < node2.val:        #            跳出                    break                else:                    node2 = node2.next        #     node后移            node = node.next        #     如果 node2 != node1 循环:            while node2 != node:        #         交换val和node2数值                temp = val                val = node2.val                node2.val = temp                node2 = node2.next        # 返回head        return head

不过同样会超时间,官网对这道题python时间要求的讨论LeetCode讨论

同样的算法使用java可以通过

public class Solution {    public ListNode insertionSortList(ListNode head) {        if(head == null){            return null;        }        if(head.next == null){            return head;        }        ListNode node = head.next;        while(node!=null){            int val = node.val;            ListNode node2 = head;            while(node2!=node){                if(val<node2.val){                    break;                } else {                    node2 = node2.next;                }            }            node = node.next;            while(node2!=node){                int temp = val;                val = node2.val;                node2.val = temp;                node2 = node2.next;            }        }        return head;    }}

练习5 LeetCode - 56. Merge Intervals

class Solution(object):    def merge(self, intervals):        """        :type intervals: List[Interval]        :rtype: List[Interval]        """        # 一开始 排除错误输入        if len(intervals) < 1:            return intervals        # 首先根据组合的开始位置,对所有组合进行排序 O(nlgn),在python3中,cmp参数被移除了        intervals = sorted(intervals,key=lambda interval:interval.start)        # 设 res 为返回的列表        res=[]        cur = Interval(0,0)        cur.start = intervals[0].start        cur.end = intervals[0].end        # 遍历排好序的list:        for i in range(1,len(intervals)):        #     如果当前interval可以和下一个interval重合:            if (cur.end+intervals[i].end-cur.start-intervals[i].start)>=(intervals[i].end-cur.start):        #         当前interval = 前后的结合                cur.end = max(intervals[i].end,cur.end)        #     否则:            else:        #         res中添加当前的interval                res.append(cur)        #         新建一个interval等于下一个interval                cur = Interval(intervals[i].start,intervals[i].end)        # 将最后一个填入res,返回res        res.append(cur)        return res

练习6 LeetCode - 148. Sort List

class Solution(object):    # 时间:O(nlgn)    # 空间:O(1)    # 那肯定是分治,这个好歹算是个快排了    def sortList(self, head):        # 如果head为空,返回空        if head == None:            return None        # 如果当前head之后next为空,也就是只有一个节点,直接返回head        if head.next == None:            return head        # 分解部分        # 设val等于head的value        val = head.val        # 设 h1 为小于head的节点头,        h1 = None        h1_index = None        # 设 h2 为大于head的节点头        h2 = None        h2_index = None        # 设 hm 为等于head的节点头        hm = head        index = head.next        hm.next = None        # 遍历链表,将链表分为重新分为三个部分:h1,h2,hm        while index!=None:            temp = index            index = index.next            temp.next = None            # 小于val的节点,插入h1            if temp.val < val:                # 如果h1为空,则h1指向当前节点,h1_index也指向当前节点                if h1 == None:                    h1 = temp                    h1_index = temp                # 否则将h1_index下一个指向temp节点,并且h1_index指向下一个                else:                    h1_index.next = temp                    h1_index = h1_index.next            # 大于等于val的节点,插入h2            elif temp.val >= val:                # 和上面的对应相同                if h2 == None:                    h2 = temp                    h2_index = temp                else:                    h2_index.next = temp                    h2_index = h2_index.next        # 对h1,h2递归的进行排序        h1 = self.sortList(h1)        h2 = self.sortList(h2)        # 将h1,hm,h2组合在一起,并返回总链的头部        if h1 != None:            h1_index =  h1            while h1_index.next!=None:                h1_index = h1_index.next            h1_index.next = hm            hm.next = h2            return h1        else:            hm.next = h2            return hm

算法还是超时了,使用归并

class Solution(object):    # 时间:O(nlgn)    # 空间:O(1)    # 那肯定是分治,同样是分治,使用归并    # 子程序 merge    def merge(self,h1,h2):        # 输入两个头结点 h1,h2        h = None        h_index = None        # 循环两个节点,直到其中一个为空        h1_index = h1        h2_index = h2        while h1_index!=None and h2_index!=None:            small = None            if h1_index.val < h2_index.val:                small = h1_index                h1_index = h1_index.next                small.next = None            else:                small = h2_index                h2_index = h2_index.next                small.next = None            if h == None:                h = small                h_index = small            else:                h_index.next = small                h_index = h_index.next        # 1空了就用2补,2空了就用1补        if h1_index == None:            h_index.next = h2_index        else:            h_index.next = h1_index        return h    # 返回并好的 h    # 输入 head    # 输出 head    def sortList(self, head):        # 基本情况:为空的时候,直接返回空;当head之后没有节点的时候,直接返回节点        if head == None or head.next == None:            return head        # 如果有两个节点,则直接返回一个排列好的        if head.next.next == None:            if head.val > head.next.val:                head.val,head.next.val = head.next.val,head.val            return head        # 分解        # 找到链表的头和中间,使用快慢指针的方式        # 令fast,slow都为head        fast = head        slow = head        # 当fast自身不为空,或之后也不为空的时候循环:        while fast!=None and fast.next!=None:        #     show后移一位            slow = slow.next        #     fast后移两位            fast = fast.next.next        # 将链表从中间分为两个部分头部分别为h1,h2,也就是h1 = head,h2 = slow.next        h1 = head        h2 = slow.next        # 同时断开链表 slow.next 设为空        slow.next = None        # 对h1,h2递归的进行排序        h1 = self.sortList(h1)        h2 = self.sortList(h2)        # 合并h1,h2为head,# 返回head        head = self.merge(h1,h2)        return head
原创粉丝点击