1.第一题。

这次周赛是我做的最差的一次,仅仅做出来一道,用时9分钟。。。哭了。

image.png

第一题很简单:用哈希表d[i]存储一下每个下标i之前的0,1数目。
这样i之后的可以用d[n-1]-d[i]求出

这样问题可以再o(n)时间内解决,代码如下。由于比赛的时候写的不够简洁。

class Solution(object):
    def maxScore(self, s):
        """
        :type s: str
        :rtype: int
        """

        n = len(s)
        max_ans = 0
        zero_num = 0
        one_num = 0

        d = {}
        for index,ch in enumerate(s):
            if ch=='0':zero_num+=1
            else:one_num+=1

            d[index] = (zero_num,one_num)


        for i in range(n-1):
            t = d[n-1][1]-d[i][1]+d[i][0]
            max_ans = max(max_ans,t)

        return max_ans

2.第二题

image.png

这一题,我慌了 没有仔细思考就直接贪心,想碰碰运气很显然出错了。
然后,我已经想到怎么做了,但是由于过于急躁,边界处理一直出错,所以也没通过,然后比赛一结束就做出来了。

和上一题类似,用一个数组存储累计和。

然后依次判断从数组左取left_pick (0~k)个从右取n-left_pick个。这个边界处理有点烦人,我不太擅长,所以没做出来。

时间复杂度为o(n)

代码如下:

class Solution(object):
    def maxScore(self, cardPoints, k):
        """
        :type cardPoints: List[int]
        :type k: int
        :rtype: int
        """
        n = len(cardPoints)
        sums = [0 for _ in range(len(cardPoints)+1)]

        for index in range(1,n+1):
            sums[index] = sums[index-1]+cardPoints[index-1]

        ans = 0
        for left_pick in range(k+1):
            left_ans = sums[left_pick]
            right_ans = sums[n]-sums[n-(k-left_pick)]
            ans = max(ans,left_ans+right_ans)

        return ans

3.对角线遍历

image.png

这个题,在我做第二题 贪心没做出来以后,开始做,感觉很容易,但是,我小看了测试用例,刚开始以为第一维度是最长的,后来发现不是。然后改呀改,发现还超时了。回头又去做第二题。坑

我的思路:暴力求解:

就是依次遍历,但是很显然这么做不够高效。 先贴出我比赛时候的代码

class Solution(object):
    def findDiagonalOrder(self, nums):
        """
        :type nums: List[List[int]]
        :rtype: List[int]
        """

        m= len(nums)
        n = max(len(x) for x in nums)
        m = n = max(m,n)

        ans = []

        for start in range(m):
            i,j = start,0
            if i>=len(nums):break

            while i>=0 and j<=n-1:
                if len(nums[i]) >= j+1:
                    ans.append(nums[i][j])
                i-=1
                j+=1

        for start in range(1,n):
            i,j = len(nums)-1,start
            while j<n and i>=0:
                if len(nums[i])>=j+1:
                    ans.append(nums[i][j])

                i-=1
                j+=1

        return ans

这里,其实浪费了很多的时间,因为矩阵很可能是一个很大且很稀疏的矩阵,但是我还是遍历了所有的地方,一共遍历了max(m,n)*max(m,n)次,其中m,n是行列的个数

优化的思路,问了一下别人,可以使用优先队列存储每个元素,将行列值和小的放前边,如果相等,则行大的放前边(因为遍历的线是左下到右上)

优化后可以确保只访问了sum(len(x) for x in nums)个数

这里我们利用python的优势,可以直接对元祖排序,所以我们将每个元素的坐标和放到第一个位置上,行的标号放到第二个位置上,元素值放到最后一个位置上,就可以非常容易的实现刚刚的想法!

代码如下:

class Solution(object):
    def findDiagonalOrder(self, nums):
        """
        :type nums: List[List[int]]
        :rtype: List[int]
        """
        queue = []
        for i,line in enumerate(nums):
            for j,item in enumerate(line):
                queue.append((i+j,-i,nums[i][j]))

        queue = sorted(queue)
        ans = [x[2] for x in queue]

        return ans

第四题:我等渣渣 不会考虑困难题的。


北语张益达
6 声望4 粉丝