每日一练 — 2021.12.12


一、最小覆盖子串

1,程序简介

  • 给你一个字符串 s 、一个字符串 t 。返回 s 中涵盖 t 所有字符的最小子串。如果 s 中不存在涵盖 t 所有字符的子串,则返回空字符串 “” 。

  • 注意:如果 s 中存在这样的子串,我们保证它是唯一的答案。

示例 1:
  • 输入:s = “ADOBECODEBANC”, t = “ABC”
  • 输出:“BANC”
示例 2:
  • 输入:s = “a”, t = “a”
  • 输出:“a”
提示:
1 <= s.length, t.length <= 105
s 和 t 由英文字母组成
进阶:你能设计一个在 o(n) 时间内解决此问题的算法吗?

2,程序代码

# -*- coding: utf-8 -*-
"""
Created on Sun Dec 12 09:48:39 2021
Function:
@author: 小梁aixj
"""
class Solution(object):
    def minWindow(self, s, t):
        ls_s, ls_t = len(s), len(t)
        need_to_find = [0] * 256
        has_found = [0] * 256
        min_begin, min_end = 0, -1
        min_window = 100000000000000
        for index in range(ls_t):
            need_to_find[ord(t[index])] += 1
        count, begin = 0, 0
        for end in range(ls_s):
            end_index = ord(s[end])
            if need_to_find[end_index] == 0:
                continue
            has_found[end_index] += 1
            if has_found[end_index] <= need_to_find[end_index]:
                count += 1
            if count == ls_t:
                begin_index = ord(s[begin])
                while need_to_find[begin_index] == 0 or\
                    has_found[begin_index] > need_to_find[begin_index]:
                    if has_found[begin_index] > need_to_find[begin_index]:
                        has_found[begin_index] -= 1
                    begin += 1
                    begin_index = ord(s[begin])
                window_ls = end - begin + 1
                if window_ls < min_window:
                    min_begin = begin
                    min_end = end
                    min_window = window_ls
        if count == ls_t:
            return s[min_begin: min_end + 1]
        else:
            return ''
if __name__ == '__main__':
    s = Solution()
    print(s.minWindow('a', 'a'))
    print(s.minWindow('ADOBECODEBANC', 'ABC'))

3,运行结果

在这里插入图片描述

二、Z 字形变换

1,程序简介

  • 将一个给定字符串 s 根据给定的行数 numRows ,以从上往下、从左到右进行 Z 字形排列。

  • 比如输入字符串为 “PAYPALISHIRING” 行数为 3 时,排列如下:

    P   A   H   N
    A P L S I I G
    Y   I   R
    
  • 之后,你的输出需要从左往右逐行读取,产生出一个新的字符串,比如:“PAHNAPLSIIGYIR”。

请你实现这个将字符串进行指定行数变换的函数:
string convert(string s, int numRows);
示例 1:
  • 输入:s = “PAYPALISHIRING”, numRows = 3
  • 输出:“PAHNAPLSIIGYIR”
示例 2:
  • 输入:s = “PAYPALISHIRING”, numRows = 4

  • 输出:“PINALSIGYAHRPI”

  • 解释:

    P     I    N
    A   L S  I G
    Y A   H R
    P     I
    
示例 3:
  • 输入:s = “A”, numRows = 1
  • 输出:“A”
提示:
1 <= s.length <= 1000
s 由英文字母(小写和大写)、',' 和 '.' 组成
1 <= numRows <= 1000
以下程序实现了这一功能,请你填补空白处内容:
class Solution
{
public:
	string convert(string s, int numRows)
	{
		if (numRows == 1)
			return s;
		int len = s.size();
		if (len <= numRows)
			return s;
		int cycle_len = 2 * numRows - 2;
		int full_cycles = len / cycle_len;
		int left = len % cycle_len;
		string r;
		int i;
		for (i = 0; i < full_cycles; ++i)
		{
			r += s[i * cycle_len];
		}
		if (left)
			r += s[i * cycle_len];
		for (i = 0; i < numRows - 2; ++i)
		{
			int j;
			for (j = 0; j < full_cycles; ++j)
			{
				r += s[j * cycle_len + i + 1];
				r += s[j * cycle_len + i + 1 + cycle_len - 2 * (i + 1)];
			}
			if (left)
			{
				_____________________
			}
		}
		for (i = 0; i < full_cycles; ++i)
			r += s[i * cycle_len + numRows - 1];
		if (left >= numRows)
			r += s[i * cycle_len + numRows - 1];
		return r;
	}
};

2,程序代码

# -*- coding: utf-8 -*-
"""
Created on Sun Dec 12 08:18:36 2021
Function:
@author: 小梁aixj
"""
import math
class Solution:
    def convert(self, s: str, numRows: int) -> str:
        n=len(s)
        N=numRows
        if n==1 or N==1:
            return s
        S=N-2
        C=2*N-2
        R=int(math.floor(n/C))
        RS=n%(C)
        CE=n-R*C
        RR=1 if (RS<=N) else 1+(RS-N)
        RX=R*(N-1)+RR
        output = []
        i = 0
        while i < N:
            j = 0 
            k = (N-1-i)
            while j < RX:
                r = int(math.floor(j/(N-1)))
                rs = j % (N-1)
                offset=i if rs == 0 else N+rs-1
                index=r*C+offset
                if index < len(s):
                    output.append(s[index])
                if i > 0 and i < N-1:
                    r=int(math.floor(k/(N-1)))
                    rs=k%(N-1)
                    offset = i if rs == 0 else N+rs-1
                    index = r*C+offset
                    if index < len(s):
                        output.append(s[index])
                j += (N-1)
                k += (N-1)
            i += 1
        return ''.join(output)
#%%
s = Solution()
print(s.convert('PAYPAYISHIRING', 3))

3,运行结果

在这里插入图片描述

三、最长有效括号

1,程序简介

  • 给你一个只包含 ‘(’ 和 ‘)’ 的字符串,找出最长有效(格式正确且连续)括号子串的长度。
示例 1:
  • 输入:s = “(()”
  • 输出:2
  • 解释:最长有效括号子串是 “()”
示例 2:
  • 输入:s = “)()())”
  • 输出:4
  • 解释:最长有效括号子串是 “()()”
示例 3:
  • 输入:s = “”
  • 输出:0
提示:
0 <= s.length <= 3 * 104
s[i] 为 '(' 或 ')'

2,程序代码

# -*- coding: utf-8 -*-
"""
Created on Sun Dec 12 08:21:18 2021
Function:
@author: 小梁aixj
"""
import pdb
class Solution(object):
    def longestValidParentheses(self, s):
        ls = len(s)
        stack = []
        data = [0] * ls
        for i in range(ls):
            curr = s[i]
            if curr == '(':
                stack.append(i)
            else:
                if len(stack) > 0:
                    data[i] = 1
                    data[stack.pop(-1)] = 1
        tep, res = 0, 0
        for t in data:
            if t in data:
                if t == 1:
                    tep += 1
                else:
                    res = max(tep, res)
                    tep = 0
        return max(tep, res)
if __name__=="__main__":
    s = Solution()
    print(s.longestValidParentheses(')()())'))

3,运行结果

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

梁辰兴

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值