算法每日一练

重新排列空格

给你一个字符串 text ,该字符串由若干被空格包围的单词组成。每个单词由一个或者多个小写英文字母组成,并且两个单词之间至少存在一个空格。题目测试用例保证 text 至少包含一个单词 。

请你重新排列空格,使每对相邻单词之间的空格数目都 相等 ,并尽可能 最大化 该数目。如果不能重新平均分配所有空格,请 将多余的空格放置在字符串末尾 ,这也意味着返回的字符串应当与原 text 字符串的长度相等。

返回 重新排列空格后的字符串 。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/rearrange-spaces-between-words
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

解答:
python3

class Solution:
    def reorderSpaces(self, text: str) -> str:
        c = text.count(" ")
        print(text)
        li = text.strip().split()
        print(li)
        if len(li) == 1:
            return li[0] + " " * c
        s, s1 = divmod(c, len(li) - 1) 
        return (" " * s).join(li)  + " " * s1

if __name__ == '__main__':
    s = Solution()
    req = s.reorderSpaces("  this   is  a sentence ")
    print(req)

有点东西: split()默认什么不加,以分割字符串中的any whitespace。divmod函数返回商和余
golang:

package main

import (
	"strings"
)

func reorderSpaces(text string) string {
    req := strings.Fields(text)
    sSpace := strings.Count(text, " ")
    k := sSpace/(len(req)-1)
    j := sSpace%(len(req)-1)
    spaceK := ""
    spaceJ := ""
    for i:=0;i<k;i++{
        spaceK += " "
    }
    if j!=0{
        for i:=0;i<j;i++{
            spaceK += " "
        }
    }
    l := strings.Join(req, spaceK) + spaceJ
    return l
}

func main(){
    reorderSpaces("  this   is  a sentence ")
}

有点东西:go中的取商和余不知道math中是否有方法,重复的字符串拼接用的for循环,go中的join是切片,字符串

重新排列数组

给你一个数组 nums ,数组中有 2n 个元素,按 [x1,x2,...,xn,y1,y2,...,yn] 的格式排列。

请你将数组按 [x1,y1,x2,y2,...,xn,yn] 格式重新排列,返回重排后的数组。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/shuffle-the-array
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
python:

class Solution:
    def shuffle(self, nums: list, n: int) -> list:
        req = []
        for i in range(n):
            req.append(nums[i])
            req.append(nums[i+n])
        return req

golang:

func shuffle(nums []int, n int) []int {
    var req []int
    for i:=0; i<n;i++{
        req = append(req, nums[i])
        req = append(req, nums[i+n])
    }
    return req
}

没东西

最少硬币组合

给定不同面额的硬币 coins 和一个总金额 amount。编写一个函数来计算可以凑成总金额所需的最少的硬币个数。如果没有任何一种硬币组合能组成总金额,返回 -1。

你可以认为每种硬币的数量是无限的。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/coin-change
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
python:

class Solution:
    def coinChange(self, coins: list, amount: int) -> int:
        dp = [float('inf')] * (amount + 1)
        dp[0] = 0

        for coin in coins:
            for x in range(coin, amount + 1):
                dp[x] = min(dp[x], dp[x - coin] + 1)
        return dp[amount] if dp[amount] != float('inf') else -1


golang

package main

import "math"
import "fmt"

func coinChange(coins []int, amount int) int {
	inf := math.Inf(1)
	reslutSlice := []float64{}
	for i := 0; i < amount+1; i++ {
		reslutSlice = append(reslutSlice, inf)
    }
    reslutSlice[0]=0
	for _, coin := range coins {
		for j := coin; j < amount+1; j++ {
			reslutSlice[j] = math.Min(reslutSlice[j], reslutSlice[j-coin]+1)
		}
    }
    for _,h := range reslutSlice{
        fmt.Println(h)
    }
	if reslutSlice[amount] != inf {
		return int(reslutSlice[amount])
	} else {
		return -1
	}

}
func main() {
	coins := []int{1, 2, 3}
    req:=coinChange(coins, 6)
    fmt.Println(req)
}

动态规划-上台阶

给定 n 节台阶,每次可以走一步或走两步,求一共有多少种方式可以走完这些台阶。

from functools import lru_cache

@lru_cache()       # cache记录,自动记录迭代中已经运算过的结果
def c_st(n):
    if n <= 2:
        return n
    return c_st(n-1) + c_st(n-2)

req = c_st(8)
print(req)

动态规划-house robber

假如你是一个劫匪,并且决定抢劫一条街上的房子,每个房子内的钱财数量各不相同。如果
你抢了两栋相邻的房子,则会触发警报机关。求在不触发机关的情况下最多可以抢劫多少钱。
Input: [2,7,9,3,1]
Output: 12

import time
from functools import lru_cache

# @lru_cache()
def test(in_list):
    if len(in_list) == 0:return 0
    if len(in_list) == 1:return in_list[0]
    if len(in_list) == 2:return max(in_list[0], in_list[1])
    cur = max(in_list[-1]+test(in_list[0:-2]), test(in_list[0:-1]))
    return cur

in_list =[2,7,9,3,1,23,4,12,43,5,23,75,523,45,77,2,34,98,3,50,34]
@lru_cache()
def test1(n):
    if n > len(in_list): return
    if n == 0:return in_list[0]
    if n == 1:return max(in_list[0], in_list[1])
    p1 = in_list[0]
    p2 = max(in_list[0], in_list[1])
    cur = 0
    for i in range(2, n+1):
        cur = max(p1+in_list[i], p2)
        p1 = p2
        p2 = cur
    return cur

有点东西:第二种压缩了空间复杂度为O(n),并且利用lru cache进行了计算结果的cache。并且总体来说for循环的运算速度好于递归。递归时间:0.015955209732055664 for循环时间0.0

动态规划-计算等差数组

给定一个数组,求这个数组中连续且等差的子数组一共有多少个。
Input: nums = [1,2,3,4]
Output: 3

def is_spl(n_list):
    if len(n_list) < 3:return False
    for i in range(len(n_list)-2):
        if n_list[i+1] - n_list[i] != n_list[i+2] - n_list[i+1]:
            return False
    return True


def test(tmp):
    if len(tmp) < 3:return 0
    a = -3
    sum = 0
    while True:

        if is_spl(tmp[a:]):
            sum += 1
        if abs(a) == len(tmp):
            break
        a -= 1

    cur = test(tmp[0:-1]) + sum
    return cur

req = test([1,2,3,4,5,6])
print("req", req)

动态规划-二维数组路径最短

给定一个 m × n 大小的非负整数矩阵,求从左上角开始到右下角结束的、经过的数字的和最
小的路径。每次只能向右或者向下移动。
Input:
[[1,3,1],
[1,5,1],
[4,2,1]]
Output: 7

a = [
    [1,3,1],
    [1,5,1],
    [4,2,1]
]
m = len(a[0])-1
n = len(a)-1
from math import inf
from functools import cache
@cache
def test(x, y):
    if x < 0 or y < 0:
        return float('inf')
    print(x, y)
    try:
        a[x][y]
    except IndexError:
        return float('inf')
    min_e = min(test(x, y-1), test(x-1, y))
    print("min_e", min_e)
    if min_e == inf:
        return a[x][y]
    else:
        return min_e + a[x][y]

req = test(2, 0)
print(req)
posted @ 2021-03-29 10:22  gege4105  Views(105)  Comments(0Edit  收藏  举报