李恒道 发表于 2024-9-23 21:40:03

https://leetcode.cn/problems/best-time-to-buy-and-sell-stock-with-cooldown/submissions/567425911/?envType=study-plan-v2&envId=dynamic-programming
缓存炸过去了
```js
var maxProfit = function (prices) {
    const cache=new Map()
    const dfs = (x) => {
      if(cache.has(x)){
            return cache.get(x)
      }
      if (x >= prices.length) {
            return 0
      }
      const buy = prices
      let maxValue = 0
      for (let index = x + 1; index < prices.length; index++) {
            const sell = prices;
            if (sell <= buy) {
                continue;
            }
            maxValue = Math.max(maxValue, dfs(index + 2) + (sell - buy))
      }
      maxValue = Math.max(maxValue, dfs(x + 1))
      cache.set(x,maxValue)
      return maxValue
    }
    return dfs(0)
};
```

wuxin0011 发表于 2024-9-24 21:10:22

本帖最后由 wuxin0011 于 2024-9-24 21:24 编辑

> 本帖最后由 wuxin0011 于 2024-9-24 21:20 编辑

> 本帖最后由 wuxin0011 于 2024-9-24 21:14 编辑

打卡

[计算右侧小于当前元素的个数](https://leetcode.cn/problems/count-of-smaller-numbers-after-self/)

这道题如果想到相关数据结构就简单了

### 相关技巧


1.**离散化**   这种技巧很常见 由于只关心大小 而不关心具体值,往往通过排序 + 二分查找排名 用排名排名代替具体数值,这种方式就是离散化。 查询复杂度为 log(n), 这个过程也可以预处理,用 hash 加速查找,能够优化到 O(1),如果值不太大,在1e6范围内可以替代因此可以用 数组代替 hash 表 查询性能为 O(1) ,数组效率常数远小于hash表 性能更优,

2.**树状数组** 这题可以说专门为这个数据结构准备的 累加和查询,本题只需要统计个数,因此 每次在对应位置更新 +1 ,题目要求统计右侧小于该位置数值个数,可以从右到左遍历


```java

class Solution {
    public List<Integer> countSmaller(int[] nums) {
      int[] a = Arrays.copyOf(nums,nums.length);
      Arrays.sort(a);
      int size = 1;
      int n = a.length;
      for(int i = 1;i < n;i++) {
            if(a != a) {
                a = a;
            }
      }
      // System.out.printf("size = %d,a = %s\n",size,Arrays.toString(a));
      int[] ans = new int;
      Fenwick f = new Fenwick(n);
      for(int i = n - 1;i >= 0;i--) {
            int val = lowerbound(a,size,nums);
            int cnt = f.sums(val - 1);
            ans = cnt;
            f.add(val,1);
      }
      List<Integer> ls = new ArrayList<>();
      for(int val : ans) ls.add(val);
      return ls;
    }

    public static int lowerbound(int[] a,int size,int t) {
            int l = 0,r = size - 1;
            while(l <= r) {
                    int mid = l + ((r - l)>> 1);
                    if(a>=t)r = mid - 1;
                    else l = mid + 1;
            }
            return l;
    }

    public static class Fenwick {
      int n;
      int[] tree, diff, a;

      public Fenwick(int[] a) {
            this.n = a.length;
            this.tree = new int;
            this.diff = new int;
            this.a = a;
      }
      public Fenwick(int n) {
            this.n = n;
            this.tree = new int;
      }

      public void init() {
            for (int i = 0; i < n; i++) {
                this.add(i, a);
            }
      }

      public int lowbit(int i) {
            return i & -i;
      }

      public void add(int i, int val) {
            int v = val;
            if (diff != null) {
                v = val - this.diff;
                this.diff = v;
            }
            i++;
            while (i <= n) {
                tree += v;
                i += lowbit(i);
            }
      }

      private int sums(int i) {
            int s = 0;
            i++;
            while (i > 0) {
                s += tree;
                i -= lowbit(i);
            }
            return s;
      }

      public int sums(int l, int r) {
            if (l < 0 || r > n || l > r) {
                return 0;
            }
            return sums(r) - sums(l - 1);
      }
    }
}
```

[提交地址](https://leetcode.cn/problems/count-of-smaller-numbers-after-self/submissions/567699694/)

时间复杂度为 nlog(n) [ 排序 nlog(n) + 二分查找 nlog(n) + 树状数组求和 nlog(n)]
空间复杂度为 o(n) (拷贝数组o(n) + 创建树状数组o(n) ]

> 用数组代替map优化后代码

```java
class Solution {
    static int N = (int)1e4 + 10;
    public List<Integer> countSmaller(int[] nums) {
      int[] a = Arrays.copyOf(nums,nums.length);
      Arrays.sort(a);
      int size = 1;
      int n = a.length;
      int max = a;
      max++;
      // 由于存在负数 -1e4, 因此需要 + 一个常量拓展数组 防止下标越界
      int[] map = new int;
      map + N] = 0;
      for(int i = 1;i < n;i++) {
            if(a != a) {
                a = a;
                map + N] = i;
            }
      }
      // System.out.printf("size = %d,a = %s\n",size,Arrays.toString(a));
      int[] ans = new int;
      Fenwick f = new Fenwick(n);
      for(int i = n - 1;i >= 0;i--) {
      // int val = lowerbound(a,size,nums);
            int val = map + N];
            int cnt = f.sums(val - 1);
            ans = cnt;
            f.add(val,1);
      }
      List<Integer> ls = new ArrayList<>();
      for(int val : ans) ls.add(val);
      return ls;

    }

    public static int lowerbound(int[] a,int size,int t) {
            int l = 0,r = size - 1;
            while(l <= r) {
                    int mid = l + ((r - l)>> 1);
                    if(a>=t)r = mid - 1;
                    else l = mid + 1;
            }
            return l;
    }

    public static class Fenwick {
      int n;
      int[] tree, diff, a;

      public Fenwick(int[] a) {
            this.n = a.length;
            this.tree = new int;
            this.diff = new int;
            this.a = a;
      }
      public Fenwick(int n) {
            this.n = n;
            this.tree = new int;
      }

      public void init() {
            for (int i = 0; i < n; i++) {
                this.add(i, a);
            }
      }

      public int lowbit(int i) {
            return i & -i;
      }

      public void add(int i, int val) {
            int v = val;
            if (diff != null) {
                v = val - this.diff;
                this.diff = v;
            }
            i++;
            while (i <= n) {
                tree += v;
                i += lowbit(i);
            }
      }

      private int sums(int i) {
            int s = 0;
            i++;
            while (i > 0) {
                s += tree;
                i -= lowbit(i);
            }
            return s;
      }

      public int sums(int l, int r) {
            if (l < 0 || r > n || l > r) {
                return 0;
            }
            return sums(r) - sums(l - 1);
      }
    }
}

```

[提交地址](https://leetcode.cn/problems/count-of-smaller-numbers-after-self/submissions/567747776/)

时间复杂度为 nlog(n) [ 排序 nlog(n) + 查找 o(1) + 树状数组求和 nlog(n)]
空间复杂度为 o(max + 1e4 + 10) (拷贝数组o(n) + 创建树状数组o(n) ] max为数组最大值

李恒道 发表于 2024-9-25 10:01:59

https://leetcode.cn/problems/best-time-to-buy-and-sell-stock-ii/
dp过了
```js
var maxProfit = function (prices) {
    const dp = new Array(2).fill(0).map(() => new Array(prices.length).fill(0))
    dp = -prices
    for (let index = 1; index < prices.length; index++) {
      dp = Math.max(dp + prices, dp)
      dp = Math.max(dp, dp - prices)
    }
    return dp
};
```

李恒道 发表于 2024-9-25 10:02:25

https://leetcode.cn/submissions/detail/567824388/
手续费,股票题基本会了
```js
var maxProfit = function (prices, fee) {
const dp = new Array(2).fill(0);
dp=new Array(prices.length).fill(0);
dp=new Array(prices.length).fill(0);
//0啥也没买
//1买入了股票
dp = -prices;
for (let index = 1; index < prices.length; index++) {
    dp = Math.max(dp, dp - prices);
    dp = Math.max(
      dp,
      dp + prices - fee
    );
}
return dp;
};
```

李恒道 发表于 2024-9-25 11:35:19

https://leetcode.cn/problems/best-time-to-buy-and-sell-stock-iii/submissions/567880494/?envType=study-plan-v2&envId=dynamic-programming
dp全写对了
但是边界问题错了
还是要练
呜呜呜
```js
var maxProfit = function (prices) {
    const dp = new Array(4).fill(0).map(() => new Array(prices.length).fill(0))
    dp = -prices
    dp =-prices
    for (let index = 1; index < prices.length; index++) {
      dp = Math.max(dp, -prices)
      dp = Math.max(dp, dp + prices)
      dp = Math.max(dp, dp - prices)
      dp = Math.max(dp, dp + prices)
    }
    return dp.pop()
};

```

李恒道 发表于 2024-9-25 15:00:34

# 热烈欢迎新朋友加入油猴中文网! 🎉🥳
❤️ 亲爱的朋友,你好呀~👋 我是油猴中文网的[**李恒道**](https://bbs.tampermonkey.net.cn/?2),另外一个管理员是[**王一之**](https://bbs.tampermonkey.net.cn/?4)。你在社区遇到的疑问都可以发帖或者私信我们💌。

## 🌟 油玩手册 📚

#### 🔍 寻找脚本

你可以在[**脚本站**](https://scriptcat.org/search)中找到你需要的脚本,也可以在[**问答互助**](https://bbs.tampermonkey.net.cn/forum-77-1.html)中进行提问💬。

#### 📄 发布脚本

如果你想把脚本发布在论坛中,你需要先发布在[**脚本站**](https://scriptcat.org/search)中,然后再在[**油猴脚本**](https://bbs.tampermonkey.net.cn/forum.php?gid=1)板块中绑定发布📢。

#### 🐟 日常闲逛

日常摸鱼你也可以通过[**搜索**](https://bbs.tampermonkey.net.cn/plugin.php?id=codfrm_recommend%3Asearch&keyword=&searchsubmit=true)与[**首页**](https://bbs.tampermonkey.net.cn/)找到你需要和想发布的内容🔍。

## 🌟 试试下面的操作,让大家更好地认识你👥:

**完善个人信息**
   - 设置个人签名 [点我修改签名](https://bbs.tampermonkey.net.cn/home.php?mod=spacecp&ac=profile&op=info) 🖊️
   - 设置一个吸引人的头像 [点我修改头像](https://bbs.tampermonkey.net.cn/home.php?mod=spacecp&ac=avatar) 📸

## 🌟 其它链接 📌

- **总版规地址:** [点击这里](https://bbs.tampermonkey.net.cn/thread-9-1-1.html) 📃
- **脚本站审查规则:** [点击这里](https://bbs.tampermonkey.net.cn/thread-3036-1-1.html) 🔍
- **回帖/回复/发帖通知** [点击这里](https://bbs.tampermonkey.net.cn/thread-5104-1-1.html) 💌

祝你在油猴中文网玩得开心!❤️🥳

李恒道 发表于 2024-9-25 15:59:22

https://leetcode.cn/problems/best-time-to-buy-and-sell-stock-iv/submissions/567956875/?envType=study-plan-v2&envId=dynamic-programming
困难题,秒了!
```js
var maxProfit = function (k, prices) {
    const dp = new Array(k * 2).fill(0).map(() => new Array(prices.length).fill(0))
    dp = -prices
    let kIndex = 0;
    while (kIndex < k * 2 - 1) {
      dp = -prices
      kIndex += 2;
    }

    for (let index = 1; index < prices.length; index++) {
      dp = Math.max(dp, -prices)
      dp = Math.max(dp, dp + prices)
      let kIndex = 2;
      while (kIndex < k * 2 - 1) {
            dp = Math.max(dp, dp - prices)
            dp = Math.max(dp, dp + prices)
            kIndex += 2;
      }
    }
    return dp.pop()
};
```

李恒道 发表于 2024-9-26 15:30:28

https://leetcode.cn/problems/unique-binary-search-trees/submissions/568254598/?envType=study-plan-v2&envId=dynamic-programming
缓存dfs秒了!
```js
var numTrees = function (n) {
    const cache = new Map()
    const generateTree = (pos, left, right) => {
      const flag = `${pos} ${left} ${right}`
      if (cache.has(flag)) {
            return cache.get(flag)
      }
      let leftNum = 0;
      for (let index = left; index < pos; index++) {
            leftNum += generateTree(index, left, pos - 1)
      }
      leftNum = leftNum == 0 ? 1 : leftNum
      let rightNum = 0;
      for (let index = pos + 1; index <= right; index++) {
            rightNum += generateTree(index, pos + 1, right)
      }
      rightNum = rightNum == 0 ? 1 : rightNum
      cache.set(flag, leftNum * rightNum)
      return leftNum * rightNum
    }
    let result = 0;
    for (let index = 1; index <= n; index++) {
      result += generateTree(index, 1, n)
    }
    return result
};
```

李恒道 发表于 2024-9-26 16:52:59

https://leetcode.cn/problems/unique-binary-search-trees-ii/submissions/568289029/?envType=study-plan-v2&envId=dynamic-programming
看了上道的解
我以为:掏dp
实际:dfs
我说怎么感觉不对劲...
```js
var generateTrees = function (n) {
    const cache = new Map()
    const generateTree = (left, right) => {
      if (left > right) {
            return
      }
      const flag = `${left} ${right}`
      if (cache.has(flag)) {
            return cache.get(flag)
      }
      let result = []
      for (let index = left; index <= right; index++) {
            let leftNum = generateTree(left, index - 1)
            let rightNum = generateTree(index + 1, right)
            for (const leftItem of leftNum) {
                for (const rightItem of rightNum) {
                  result.push({
                        val: index,
                        left: leftItem,
                        right: rightItem
                  })
                }
            }
      }
      cache.set(flag, result)
      return result
    }
    return generateTree(1, n)
};
```

李恒道 发表于 2024-9-26 16:54:53

https://leetcode.cn/problems/add-two-integers/?envType=study-plan-v2&envId=primers-list
水一道练练go
```go
func sum(num1 int, num2 int) int {
    return num1+num2
}
```
页: 8 9 10 11 12 13 14 15 16 17 [18] 19 20 21 22 23 24 25 26 27
查看完整版本: 【当前排名67359】挑战leetcode进入前1w名