算法刷题 1-5

算法刷题 1-5

一直忘了刷题,要抓紧了!!! 以下代码基本都是本萌新手撸,大佬请无视。

1

给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。

你可以假设每种输入只会对应一个答案。但是,你不能重复利用这个数组中同样的元素。

示例:

给定 nums = [2, 7, 11, 15], target = 9

因为 nums[0] + nums[1] = 2 + 7 = 9 所以返回 [0, 1]

1.1

两层遍历,效果不好,4000ms

	alist = []
        for index,item in enumerate(nums):
            for nextitem in range(index+1, len(nums)):
               if item + nums[nextitem] == target:
                    alist.append(index)
                    alist.append(nextitem)
                    return alist

1.2

另外一种思路,注意 if ... in ... 的使用。 600ms

	lens = len(nums)
        j=-1
        for i in range(1,lens):
            temp = nums[:i]
            if (target - nums[i]) in temp:
                j = temp.index(target - nums[i])
                break
        if j>=0:
            return [j,i]

1.3

注意使用hashmap,是个好东西。40ms

	hashmap={}
        for ind,num in enumerate(nums):
            hashmap[num] = ind
        for i,num in enumerate(nums):
            j = hashmap.get(target - num)
            if j is not None and i!=j:
                return [i,j]

2 ⚠️

给出两个 非空 的链表用来表示两个非负的整数。其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字。

如果,我们将这两个数相加起来,则会返回一个新的链表来表示它们的和。

您可以假设除了数字 0 之外,这两个数都不会以 0 开头。

示例:

输入:(2 -> 4 -> 3) + (5 -> 6 -> 4) 输出:7 -> 0 -> 8 原因:342 + 465 = 807

2.1

第一次接触ListNode,生成这个单链表,可以使用

# Definition for singly-linked list.
class ListNode:
    def __init__(self, x):
        self.val = x
        self.next = None
        
l1 = ListNode(2)
l1.next = ListNode(4)
tmp = l1.next
tmp.next = ListNode(3)

l2 = ListNode(5)
l2.next = ListNode(6)
tmp = l2.next
tmp.next = ListNode(4)

输出ListNode的值,可以使用

# print listnode value
node = result
while node:
    print(node.val)
    node = node.next

解答: 注意ListNode的操作方法!!!//10除10取整数

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution:
    def addTwoNumbers(self, l1: ListNode, l2: ListNode) -> ListNode:
        ans = ListNode(0)
        tmp = ans
        tmpsum = 0
        while True:
            #依次遍历l1 l2,对应位相加
            if l1 != None:
                tmpsum += l1.val
                l1 = l1.next
            if l2 != None:
                tmpsum += l2.val
                l2 = l2.next
            tmp.val = tmpsum % 10     # 除10取余作为当前位的值
            tmpsum //= 10                #除10取整,即高位,作为指针的下个结点 进行加法运算
            if l1 == None and l2 == None and tmpsum == 0:
                break
            tmp.next = ListNode(0)
            tmp = tmp.next
        return ans

3 ⚠️

给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。

示例 1:

输入: "abcabcbb" 输出: 3 解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。 示例 2:

输入: "bbbbb" 输出: 1 解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。 示例 3:

输入: "pwwkew" 输出: 3 解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。   请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。

3.1

参考了下面的文章,写的程序滑动窗口

s="dvdfvdfdd"

hashmap = {}
start = 0
end = 0
ans = 0
for ind in range(0,len(s)):
    j = hashmap.get(s[ind])
    if j is None:
        hashmap[s[ind]] = ind
        end = ind + 1
    else:
        # 保留答案
        ans = max(end-start,ans)
        # 虽然之前出现过,但是之前已经有别的字发生了重复 例如abba的最后一个a,但是b在a之前已经重复
        if start > hashmap[s[ind]]:
            hashmap[s[ind]] = ind
            end = ind + 1
        else:
            # 更新start位置为重复项上一次出现的位置的后一个位置 例如 abcba, 运行到第二个b,那么start从第一个b后面一位开始
            start = hashmap[s[ind]]+1
            hashmap[s[ind]] = ind
            end = ind + 1
            
    ans = max(end-start,ans)
    print(hashmap,ans, start, end)

print(ans)

4

给定两个大小为 m 和 n 的有序数组 nums1 和 nums2。

请你找出这两个有序数组的中位数,并且要求算法的时间复杂度为 O(log(m + n))。

你可以假设 nums1 和 nums2 不会同时为空。

示例 1:

nums1 = [1, 3] nums2 = [2]

则中位数是 2.0

示例 2:

nums1 = [1, 2] nums2 = [3, 4]

则中位数是 (2 + 3)/2 = 2.5

4.1

用上python自带的函数,很简单

	nums1.extend(nums2)
        nums1.sort()
        mod = len(nums1) % 2
        center = len(nums1) / 2
        if mod == 0:
            # 是偶数
            ans = (nums1[int(center - 1)] + nums1[int(center)])/2
        else:
            ans = nums1[math.floor(center)]

        return ans

5

给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为 1000。

示例 1:

输入: "babad" 输出: "bab" 注意: "aba" 也是一个有效答案。

示例 2:

输入: "cbbd" 输出: "bb"

5.1

回文就是 “上海自来水来自海上”这种。这个题目想了很久,总是会有一些问题,后来推翻重写,先判断中心点,再在中心点往两侧找。

感觉效果还不错,速度超过了87%的人。注意 [::-1] 字符串翻转。

	ans = s[0] if len(s)>0 else ""
        nowtext = s[0] if len(s)>0 else ""
        start = 0
        end = 0
        for index, text in enumerate(s):
            
            if nowtext == text:
		# 相同的内容,例如ggg,aaaa,当作中心点
                end += 1
		# 例如abbb就结束了
                if index + 1 == len(s):
                    if len(s[start:end])>len(ans):
                        ans = s[start:end]
            else:
                if len(s[start:end]) > len(ans):
                    ans = s[start:end]
                    
                # 找两侧
                # print("中心点",s[start:end])
                # print(index, end, start,range(1,min(start+1,len(s)-end+1)))
                
		
		# aaa b aacccccac 因为左侧只有3个,所以比到3就好了。
                for i in range(1,min(start+1,len(s)-end+1)):
                    # print('左右',s[start-i:start],s[end:end+i][::-1])
                    if s[start-i:start] == s[end:end+i][::-1]:
                        if len(s[start-i:end+i]) > len(ans):
                            ans = s[start-i:end+i]
                    else:
			# 如果最近几个就对不上,就不用对后面的了
                        break
                    
               
                start = index
                end = index + 1
                nowtext = text
                
        
       
        print('answer',ans)
        return ans

三个小时才写了5题,我可真是太菜了。

正在加载评论区