AcWing
  • 首页
  • 课程
  • 题库
  • 更多
    • 竞赛
    • 题解
    • 分享
    • 问答
    • 应用
    • 校园
  • 关闭
    历史记录
    清除记录
    猜你想搜
    AcWing热点
  • App
  • 登录/注册

$~$

作者: 作者的头像   迷弟 ,  2020-07-29 01:37:43 ,  所有人可见 ,  阅读 647


1



这个帖子sequence /39870/留着以后写
这样写的时候就是几十天之后的沉贴,太机智了, 偷偷


15日前不更新这一篇了,就发在题解好了,避免太长


Explore Card大作战: Version: 0.8August全勤Challenge
$1.$ Detect Capital #LC.520

return word[1:]==word[1:].lower() or word==word.upper() #python
bool detectCapitalUse(string word) { //bool返回(即判断)True/False #c++
    for(int i = 1; i < word.size(); i++){
        if(isupper(word[1]) != isupper(word[i]) || 
           islower(word[0]) && isupper(word[i])) return false;
    }        
    return true;
}

$2.$ Design HashSet #LC.705

  • add(value): Insert a value into the HashSet.
  • contains(value) : Return whether the value exists in the HashSet or not.
  • remove(value): Remove a value in the HashSet. If the value does not exist in the HashSet, do nothing.

Solution

class MyHashSet:

    def __init__(self):
        self.arr = [None] * 8
        self.capacity = 8
        self.size = 0
        self.thres = 2 / 3

    def hash(self, key): return key % self.capacity

    def rehash(self, key): return (5 * key + 1) % self.capacity

    def insertPos(self, key):
        pos = self.hash(key)
        #using -1 to represent the "removed" item
        while self.arr[pos] is not None:
            if self.arr[pos] == key: return -1
            #here is the small bug, the following item may contain the key
            if self.arr[pos] == -1: break
            pos = self.rehash(pos)
        return pos

    def safeAdd(self, key):
        pos = self.insertPos(key)
        #already in, 
        if pos == -1: return 
        self.arr[pos] = key
        self.size += 1

    def safeAddArr(self, arr):
        for val in arr: 
            if val is not None: self.safeAdd(val)

    def add(self, key: int) -> None:
        def preAdd(self):
            if self.size / self.capacity <= self.thres: return 
            self.capacity <<= 1
            oldArr, self.arr = copy.deepcopy(self.arr), [None] * self.capacity
            self.safeAddArr(oldArr)

        preAdd(self)
        #fix the small bug by precheck before add
        if self.contains(key): return
        self.safeAdd(key)

    def remove(self, key: int) -> None:
        pos = self.hash(key)
        while self.arr[pos] is not None:
            if self.arr[pos] == key: 
                #you cannot assign None, because you will lose track of continuous items
                self.arr[pos] = -1
                self.size -= 1
                return
            pos = self.rehash(pos)
        return

    def contains(self, key: int) -> bool:
        pos = self.hash(key)
        while self.arr[pos] is not None:
            if self.arr[pos] == key: return True
            pos = self.rehash(pos)
        return False
# Your MyHashSet object will be instantiated and called as such:
# obj = MyHashSet()
# obj.add(key)
# obj.remove(key)
# param_3 = obj.contains(key)

$3.$ LC114. 二叉树展开为链表
给定一个二叉树,原地将它展开为一个单链表。#注:要记得把左子树置空 (避免环)

class Solution:
    def flatten(self, root: TreeNode) -> None:
        """
        Do not return anything, modify root in-place instead.
        """
        if(root == None): return
        self.flatten(root.left)
        self.flatten(root.right)
        tmp = root.right
        root.right = root.left
        root.left = None
        while(root.right != None): root = root.right
        root.right = tmp
注释#先把左右子树捋直 (可删)
        self.flatten(root.left)
        self.flatten(root.right)
        tmp = root.right #把捋直的右子树备份一下
        root.right = root.left #把捋直的左子树放到右边
        root.left = None #记得把左子树置空
        while(root.right): #找到现在右子树的最后一个node
            root = root.right
        root.right = tmp #把捋直的原来的右子树接上去

c++版一样 都是递归,不过self不需要 直接flatten(root.left).. etc.


$4. $Valid Palindrome
Given a string, determine if it is a palindrome, considering only alphanumeric characters and ignoring cases.

Input: "A man, a plan, a canal: Panama" Output: true
c++Solution

class Solution {
public:
    bool isPalindrome(string s) {
    for (int i = 0, j = s.size() - 1; i < j; i++, j--) { // Move 2 pointers from each end until they collide
        while (isalnum(s[i]) == false && i < j) i++; // Increment left pointer if not alphanumeric
        while (isalnum(s[j]) == false && i < j) j--; // Decrement right pointer if no alphanumeric
        if (toupper(s[i]) != toupper(s[j])) return false; // Exit and return error if not match
    }

    return true;
}
};

$6.$ LC.442.Find All Duplicates in an Array
Rearragnge number重排列 O(n) time/O(1) space

class Solution(object):
    def findDuplicates(self, nums):
        for i in range(len(nums)):
            while i != nums[i] - 1 and nums[i] != nums[nums[i]-1]:
                nums[nums[i]-1], nums[i] = nums[i], nums[nums[i]-1]

        return [nums[it] for it in range(len(nums)) if it != nums[it] - 1]

  1. Iterator for Combination 字母组合迭代器 迭代排列组合
    位运算 Bit manipulation
set<string>GenaretallComb(string s,int len){
    int mask = 1<<s.length();
    set<string>hold;
    string comString = "";
    for(int no=1;no<mask;no++){
        int num = no,i = 0;
        while(num){
            if(num&1)comString = comString + s[i];
            i++,num>>=1;
        }
        if(comString.length()==len)hold.insert(comString);
        comString = "";
    }
    return hold;
}

class CombinationIterator {
public:
    set<string>st;
    set <string> :: iterator cur;
    CombinationIterator(string characters, int combinationLength) {
        this->st = GenaretallComb(characters,combinationLength);
        this->cur = begin(st);
    }

    string next() {
        return !(cur==end(st))?*cur++:"";
    }

    bool hasNext() {
        return !(cur==end(st));
    }
};

python版

class CombinationIterator:

    def __init__(self, characters: str, combinationLength: int):
        self.characters = characters
        self.n = len(characters)
        self.combinations = gen_combinations(self.n, combinationLength)
        self.ind = len(self.combinations) - 1

    def next(self) -> str:
        s = ""
        for i in range(self.n):
            if self.combinations[self.ind][i] != "0":
                s += self.characters[i]
        self.ind -= 1
        return s

    def hasNext(self) -> bool:
        return self.ind > -1 

def gen_combinations(l, n):
    end = int("1" * l, 2)
    ans = []
    for i in range(end + 1):
        b = bin(i)[2:]
        if b.count('1') == n:
            ans.append(b.zfill(l))
    return ans

$17.$ 买卖股票的最佳时机 III
【$\color{#66ccff}{记忆化}$递归】
-挺万能的方法。具体可根据递归代码来理解变化过程

class Solution:
    def maxProfit(self, prices):
        n = len(prices)
        if n < 2:
            return 0
        dp1 = [0 for _ in range(n)]
        dp2 = [0 for _ in range(n)]
        minval = prices[0]
        maxval = prices[-1]
        #前向   
        for i in range(1,n):
            dp1[i] = max(dp1[i-1], prices[i] - minval)
            minval = min(minval, prices[i])
        #后向    
        for i in range(n-2,-1,-1):
            dp2[i] = max(dp2[i+1], maxval - prices[i])
            maxval = max(maxval, prices[i])

        dp = [dp1[i] + dp2[i] for i in range(n)]
        return max(dp)

c++版递归

TLE


class Solution {
public:
    int maxProfit(vector<int>& prices) {
        return f(prices, 0, 0, 0);
    }

    /**
     *
     * @param prices
     * @param i 当前考虑第几天
     * @param hasStock 是否有股票在手
     * @param counts 已经交易的次数(每买一次股票就加一)
     * @return
     */
private:
    int f(vector<int>& prices, int i, int hasStock, int counts) {
        // 如果已经买了两次股票,并且手里已经没有股票了,那么后面的天数不需要考虑
        if(i >= prices.size() || (counts >= 2 && hasStock < 1))
            return 0;
        // 如果手里有股票,我可以选择卖或者不卖
        if(hasStock > 0)
            return  max(prices[i] + f(prices, i+1, 0, counts), f(prices, i+1, 1, counts));
        // 如果没有股票,我可以选择买或者不买
        return max(-prices[i] + f(prices, i+1, 1, counts+1), f(prices, i+1, 0, counts));
    }   
};

自己修改的c++版 52 ms 5.89%

class Solution {
public: int maxProfit(vector<int> prices) {
        int m = prices.size();
        vector<vector<vector<int>>> dp(m+1, vector<vector<int>>(2+1, vector<int>(2,0)));
        dp[0][2][1] = dp[0][1][1] = -1e8;
        dp[0][2][1] = dp[0][1][1] = -1e8;
        for(int i = 1; i<=m; i++)
            for(int k=1; k<=2; k++){  //表示用了k次交易
                dp[i][k][0] = max(dp[i-1][k][1] + prices[i-1], dp[i-1][k][0]);
                dp[i][k][1] = max(dp[i-1][k-1][0] - prices[i-1], dp[i-1][k][1]);
            }
        return max(dp[m][1][0], dp[m][2][0]);
    }
};

java版

public int maxProfit(int[] prices) {
        int len = prices.length;
        if (len == 0) return 0;
        int k = 2;
        int[][][] dp = new int[len][k+1][2];

        for(int i = 0; i < len; i ++){
            for(int j = k; j > 0; j --){
                if (i == 0){
                    //第i天,还有j次,手里没有股票,当i=0,手里没股票,最大利润为0
                    dp[i][j][0] = 0;
                    //当i=0,手里有股票,因为还没有盈利,最大利润为 负prices[i]
                    dp[i][j][1] = -prices[i];
                    continue;
                }
                //今天手里没股票,比较MAX(前一天可能没股票,前一天有股票但是今天卖出去了,卖出去就有利润,所以+ prices[i])
                dp[i][j][0] = Math.max(dp[i-1][j][0], dp[i-1][j][1] + prices[i]);
                //今天手里有股票,比较MAX(前一天可能有股票,前一天没股票但是今天买了,买了就有成本,所以- prices[i])
                dp[i][j][1] = Math.max(dp[i-1][j][1], dp[i-1][j-1][0] - prices[i]);
            }
        }
        return dp[len-1][k][0];
    }

5 评论


用户头像
ACwisher   2020-08-15 11:47         踩      回复

过来看看((

用户头像
迷弟   2020-08-15 12:27         踩      回复

哈哈哈 我都没怎么写思路 只有代码hhh 过几天写hh


用户头像
MournInk   2020-07-29 15:46         踩      回复

禁止留空!


用户头像
ACwisher   2020-07-29 07:26         踩      回复

收藏了


用户头像
ACwisher   2020-07-29 07:26         踩      回复

有道理,但我会愉快地点进你的主页


App 内打开
你确定删除吗?
1024
x

© 2018-2025 AcWing 版权所有  |  京ICP备2021015969号-2
用户协议  |  隐私政策  |  常见问题  |  联系我们
AcWing
请输入登录信息
更多登录方式: 微信图标 qq图标 qq图标
请输入绑定的邮箱地址
请输入注册信息