编程能力提升_5

目录

1.给定一个非负整数 numRows,生成杨辉三角的前 numRows 行。

2.给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格。设计一个算法来计算你所能获取的最大利润。

3.给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格。设计一个算法来计算你所能获取的最大利润。你可以尽可能地完成更多的交易(多次买卖一支股票)。

4.给定一个字符串,验证它是否是回文串,只考虑字母和数字字符,可以忽略字母的大小写。

5.给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。

6.给定一个链表,判断链表中是否有环。

7.设计一个支持 push,pop,top 操作,并能在常数时间内检索到最小元素的栈。

8.编写一个程序,找到两个单链表相交的起始节点


 

1.给定一个非负整数 numRows,生成杨辉三角的前 numRows 行。

在杨辉三角中,每个数是它左上方和右上方的数的和。

示例:

输入: 5
输出:
[
     [1],
    [1,1],
   [1,2,1],
  [1,3,3,1],
 [1,4,6,4,1]
]

方法一:

class Solution(object):
    def generate(self, numRows):
        """
        :type numRows: int
        :rtype: List[List[int]]
        """
        def builtls(ls):
            newls=[1]*(len(ls)+1)
            #因为最左端和最右端都是1,所以不进行更新,只更新中间部分
            for i in range(1,len(ls)):
                newls[i]=ls[i-1]+ls[i]
            return newls   
        
        if numRows==0:
            return []       
        retr=[[1]]
        for i in range(1,numRows):
            retr.append(builtls(retr[-1]))
        return retr

wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

方法二:

class Solution:    
    def generate(self, numRows):
        """
        :type numRows: int
        :rtype: List[List[int]]
        """
        result = []
        for i in range(numRows):
            #第几行就有几个数,先构造出
            now = [1]*(i+1)
            #当i大于等于2时,now会发生变化
            if i >= 2:
                for n in range(1,i):
                    now[n] = pre[n-1]+pre[n]
            #将当前行加到列表里
            result.append(now)
            pre = now
        return result

wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

2.给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格。设计一个算法来计算你所能获取的最大利润。

注意你不能在买入股票前卖出股票。

示例 1:

输入: [7,1,5,3,6,4]
输出: 5
解释: 在第 2 天(股票价格 = 1)的时候买入,在第 5 天(股票价格 = 6)的时候卖出,最大利润 = 6-1 = 5 。
     注意利润不能是 7-1 = 6, 因为卖出价格需要大于买入价格。否则输出0

方法一:

class Solution:
    def maxProfit(self, prices: List[int]) -> int:        
        #动态规划 前i天的最大收益 
        #= max{前i-1天的最大收益,第i天的价格-前i-1天中的最小价格}
        if prices==[]:
            return 0
        maxp=0
        min_getin=prices[0]
        for i in range(len(prices)):
            min_getin=min(min_getin,prices[i])
            maxp=max(maxp,prices[i]-min_getin)
        return maxp

方法二:但是执行时间长,复杂度大

class Solution(object):
    def maxProfit(self, prices):
        """
        :type prices: List[int]
        :rtype: int
        """
        differ=0
        for i in range(len(prices)):
            if max(prices[i:])-prices[i]>differ:
                differ=max(prices[i:])-prices[i]
        return differ

3.给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格。设计一个算法来计算你所能获取的最大利润。你可以尽可能地完成更多的交易(多次买卖一支股票)。

注意:你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。

示例 1:

输入: [7,1,5,3,6,4]
输出: 7
解释: 在第 2 天(股票价格 = 1)的时候买入,在第 3 天(股票价格 = 5)的时候卖出, 这笔交易所能获得利润 = 5-1 = 4 。
     随后,在第 4 天(股票价格 = 3)的时候买入,在第 5 天(股票价格 = 6)的时候卖出, 这笔交易所能获得利润 = 6-3 = 3 。
class Solution(object):
    def maxProfit(self, prices):
        """
        :type prices: List[int]
        :rtype: int
        """
        #根据题目的意思,当天卖出以后,当天还可以买入,
        #所以算法可以直接简化为只要今天比昨天大,就卖出。
        profit = 0
        for day in range(len(prices)-1):
            differ = prices[day+1] - prices[day]
            if differ > 0:
                profit += differ
        return profit

4.给定一个字符串,验证它是否是回文串,只考虑字母和数字字符,可以忽略字母的大小写。

示例 1:

输入: "A man, a plan, a canal: Panama"
输出: true
class Solution:
    def isPalindrome(self, s: str) -> bool:
        s = ''.join(filter(str.isalnum,s)).lower()
        return s==s[::-1]

5.给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。

你的算法应该具有线性时间复杂度。 你可以不使用额外空间来实现吗?

示例 1:

输入: [2,2,1]
输出: 1

方法一:但是比较耗时

class Solution:
    def singleNumber(self, nums: List[int]) -> int:        
        while nums!=None:
            temp=nums.pop()
            if temp in nums:
                nums.remove(temp)
            else:
                return temp

方法二:

class Solution:
    def singleNumber(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        a = 0
        #除了某个元素只出现一次以外,其余每个元素均出现两次。
        #因此所有的数除奇次以外,异或后等于0,而0^0=0
        for num in nums:
            a = a ^ num
        return a

6.给定一个链表,判断链表中是否有环。

方法一:

 

class Solution(object):
    def hasCycle(self, head):
        """
        :type head: ListNode
        :rtype: bool
        """
        save = set()
        cur = head 
        while cur is not None:
            if cur in save:
                return True
            else:#将当前指针加到集合中
                save.add(cur)
                cur = cur.next
        #如果cur为空,则一定无环
        return False  
类似方法
class Solution(object):
    def hasCycle(self, head):
        """
        :type head: ListNode
        :rtype: bool
        """
        list_id = []
        while head:
            if id(head) in list_id:
                return True
            list_id.append(id(head))
            head = head.next
        return False

方法二:快慢指针法:

# Definition for singly-linked list.
# class ListNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.next = None
class Solution(object):
    def hasCycle(self, head):
        fast =head
        low = head
        while fast is not None and fast.next is not None:            
            fast = fast.next
            if fast == low or fast.next==low:
                return True
            fast = fast.next
            low = low.next
        return False

7.设计一个支持 push,pop,top 操作,并能在常数时间内检索到最小元素的栈。

  • push(x) -- 将元素 x 推入栈中。
  • pop() -- 删除栈顶的元素。
  • top() -- 获取栈顶元素。
  • getMin() -- 检索栈中的最小元素。

示例:

MinStack minStack = new MinStack();
minStack.push(-2);
minStack.push(0);
minStack.push(-3);
minStack.getMin();   --> 返回 -3.
minStack.pop();
minStack.top();      --> 返回 0.
minStack.getMin();   --> 返回 -2.
class MinStack(object):

    def __init__(self):
        """
        initialize your data structure here.
        """
        self.stack = []
        self.minstack = []

    def push(self, x):
        """
        :type x: int
        :rtype: void
        """
        self.stack.append(x)
        if self.minstack == [] or x <= self.minstack[-1]:
            self.minstack.append(x)

    def pop(self):
        """
        :rtype: void
        """
        #如果弹出的是最小值在末尾,则将最小值列表和原来列表
        #中的最小元素都弹出
        if self.stack != []:
            if self.stack[-1] == self.minstack[-1]:
                self.minstack.pop()
            self.stack.pop()

    def top(self):
        """
        :rtype: int
        """
        if self.stack != []:
            return self.stack[-1]
        else:
            return None

    def getMin(self):
        """
        :rtype: int
        """
        if self.minstack != []:            
            return self.minstack[-1]
        else:
            return None

8.编写一个程序,找到两个单链表相交的起始节点

方法一:


class Solution(object):
    def getIntersectionNode(self, headA, headB):
        """
        :type head1, head1: ListNode
        :rtype: ListNode
        """
        save = set()
        curA=headA
        while curA is not None:
            save.add(curA)
            curA=curA.next
              
        cur = headB
        while cur is not None:
            if cur in save:
                return cur
            else:#将当前指针加到集合中
                cur = cur.next
        #如果cur为空,则一定无环
        return None

方法二:

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

class Solution(object):
    def getIntersectionNode(self, headA, headB):
        """
        :type head1, head1: ListNode
        :rtype: ListNode
        """
        #同时对A和B进行遍历, 并且让到达末尾的指针指向另一个链表的头结点.
        #例如A: 6->7->4->5; B: 1->2->3->4->5 
        #遍历时会相交于4 (67451234, 12345674). 
        #不相交,因为最后会两个串都粘贴对方,所以不相交的话,q,p都是None
        if not headA or not headB:
            return None
        p,q = headA,headB
        while p!=q:
            p = p.next if p else headB
            q = q.next if q else headA
        return p   

 

 

 

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值