leetcode每周3道

16、最接近的三数之和

把三数和转化为两数和:固定住一个数,求出sum=target-这个数,在剩下的数中用双指针找到和sum最接近的值。

时O(nlogn+n^2)=O(n^2)  额外空O(1) 排序O(logn)

优化思路:

(1)三数和=target时直接return target

(2)加一个判重操作,如果left+=1或者right-=1之后的数和left/right之前的值一样直接往下移。

(3)mark的初值不用再循环中每次判断,直接在循环之外用随便三个nums[i]的值初始化即可,但是绝对不能自己设定初始化的值。

class Solution(object):
    def threeSumClosest(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: int
        """
        nums.sort()
        l = len(nums)
        mark = 0
        for i in range(l):
            sum = target - nums[i]
            left = i+1
            right = l-1
            while left < right:
                tmp = sum - (nums[left] + nums[right])
                if i == 0 and left == 1 and right == l-1: #用第一个值初始化mark
                    mark = tmp
                else:
                    if abs(tmp) < abs(mark):
                        mark = tmp
                if tmp == 0:
                    return target
                elif tmp > 0:
                    left +=1
                else:
                    right -=1

        return target - mark

17、电话号码的字母组合

1、回溯法,用递归模板

2、递归是DFS,改为BFS,用队列做,三重循环,第一层遍历数字,第二层循环把当前队列里的字符串出队,第三层循环把下一个数字对应的字符与出队的字符串相连接入队。

 

class Solution(object):
    def letterCombinations(self, digits):
        """
        :type digits: str
        :rtype: List[str]
        """
        if digits == '':
            return []
        phone = ['abc','def','ghi','jkl','mno','pqrs','tuv','wxyz']
        ans = []
        patch = []
        l = len(digits)

        def backtracking(digits,index):     #参数 index对应:控制了迭代循环最外层的次数 即数字个数
            if index == l:                  #终止条件            
                ans.append(''.join(patch))  #收集结果
                return                      #return
            for i in phone[ord(digits[index]) - 50]: #第二层循环 处理集合元素
                patch.append(i)                      #处理节点 
                backtracking(digits,index+1)         #递归 第三层循环
                patch.pop()                          #回溯

        backtracking(digits,0)
        return ans
        

问题:这里patch定义为全局变量 ,但是在终止条件那里如果写ans.append(patch),会报错说局部变量patch未指定,这是为什么,改为ans.apppend('',join(patch))就不会报错了。

class Solution(object):
    def letterCombinations(self, digits):
        """
        :type digits: str
        :rtype: List[str]
        """
        if digits == '':
            return []
        phone = ['abc','def','ghi','jkl','mno','pqrs','tuv','wxyz']
        ans = ['']
        for i in digits:
            l = len(ans)
            for _ in range(l):
                tmp = ans.pop(0)
                for j in phone[ord(i) - 50]:  #ord[i]-48的结果是2对应2,0对应0 
                                              #但是这里phone的第0个元素对应2,所以-48变成了-50
                    ans.append(tmp + j)
        return ans

19、删除链表的倒数第N个结点

1、先遍历链表看一共有几个结点,再减去倒数就得到正数第几个结点。

对于特殊情况(仅有一个结点,去除头节点)特殊处理。

2、先后指针,快指针先走n步,随后再快慢指针一起走,当快指针到末尾时,慢指针就到了倒数第n个结点的前一个结点。注意要特殊处理删除头节点,即倒数第n个为头节点的情况。

 如果不特殊处理头节点,就要新建一个结点dummy.next指向头节点,让慢指针也等于这个结点dummy,最后return dummy.next

3、也可以用栈实现,先入栈,再出栈,第n个出来的即为倒数第n个,栈顶元素即为倒数n-1个。

# Definition for singly-linked list.
# class ListNode(object):
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution(object):
    def removeNthFromEnd(self, head, n):
        """
        :type head: ListNode
        :type n: int
        :rtype: ListNode
        """
        index = head 
        if head.next == None: #如果只有一个结点 那肯定返回None
            return None           
        l = 0
        while head: #计数一共有多少个结点
            head = head.next
            l+=1
 
        t = l - n  #记录是正数第几个节点
        if t == 0: #如果要去除的是正数第1个节点 直接return index.next
            return index.next        
        head = index #否则要一直遍历到第t个结点 
        while t > 0:
            t-=1
            tmp = head
            head = head.next
        tmp.next = head.next
        return index
# Definition for singly-linked list.
# class ListNode(object):
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution(object):
    def removeNthFromEnd(self, head, n):
        """
        :type head: ListNode
        :type n: int
        :rtype: ListNode
        """
        fast = slow = head
        while n>0: #让快指针先走n步
            fast = fast.next
            n-=1
        if fast == None: #如果此时快指针为空,即要删的是头节点直接return head.next
            return head.next
        while fast and fast.next: #否则快指针走到链表结尾时,慢指针正好走到了倒数第n个结点的前一个
            fast = fast.next
            slow = slow.next
        slow.next = slow.next.next
        return head

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值