当前位置: 首页 > wzjs >正文

旅游网站开发的结论优化精灵

旅游网站开发的结论,优化精灵,网站维护好的方法,网站建设咨询公司地址LeetCode题目: 669. 修剪二叉搜索树108. 将有序数组转换为二叉搜索树538. 把二叉搜索树转换为累加树2179. 统计数组中好三元组数目(每日一题)307. 区域和检索 - 数组可修改(树状数组)122. 买卖股票的最佳时机 II309. 买卖股票的最佳时机含冷冻期188. 买卖股票的最佳时机 IV 其他…

LeetCode题目:

  • 669. 修剪二叉搜索树
  • 108. 将有序数组转换为二叉搜索树
  • 538. 把二叉搜索树转换为累加树
  • 2179. 统计数组中好三元组数目(每日一题)
  • 307. 区域和检索 - 数组可修改(树状数组)
  • 122. 买卖股票的最佳时机 II
  • 309. 买卖股票的最佳时机含冷冻期
  • 188. 买卖股票的最佳时机 IV

其他:

今日总结
往期打卡


669. 修剪二叉搜索树

跳转: 669. 修剪二叉搜索树

学习: 代码随想录公开讲解

问题:

给你二叉搜索树的根节点 root ,同时给定最小边界low 和最大边界 high。通过修剪二叉搜索树,使得所有节点的值在[low, high]中。修剪树 不应该 改变保留在树中的元素的相对结构 (即,如果没有被移除,原有的父代子代关系都应当保留)。 可以证明,存在 唯一的答案

所以结果应当返回修剪好的二叉搜索树的新的根节点。注意,根节点可能会根据给定的边界发生改变。

在这里插入图片描述

思路:

这题需要利用二叉搜索树的性质
遍历,如果小于边界搜右边代替自己返回,如果大于自己搜左边代替自己返回

复杂度:

  • 时间复杂度: O ( n ) O(n) O(n)
  • 空间复杂度: O ( 1 ) O(1) O(1)

代码(前序遍历):

class Solution {public TreeNode trimBST(TreeNode root, int low, int high) {if(root==null) return null;if(root.val<low) return trimBST(root.right,low,high);if(root.val>high) return trimBST(root.left,low,high);root.left = trimBST(root.left,low,high);root.right = trimBST(root.right,low,high);return root;        }
}

108. 将有序数组转换为二叉搜索树

跳转: 108. 将有序数组转换为二叉搜索树

学习: 代码随想录公开讲解

问题:

给你一个整数数组 nums ,其中元素已经按 升序 排列,请你将其转换为一棵 平衡 二叉搜索树。

在这里插入图片描述

思路:

平衡二叉树是指该树所有节点的左右子树的高度相差不超过1
所以这题需要对数组二分.
每次平分数组向下遍历到 l>=r 即可

复杂度:

  • 时间复杂度: O ( n ) O(n) O(n)
  • 空间复杂度: O ( 1 ) O(1) O(1)

代码(前序遍历):

class Solution {TreeNode buildTree(int[] nums,int left,int right){if(left>=right) return null;int mid = (left+right)/2;TreeNode root = new TreeNode(nums[mid]);if(right-left==1) return root;root.left = buildTree(nums,left,mid);root.right = buildTree(nums,mid+1,right);return root;}public TreeNode sortedArrayToBST(int[] nums) {return buildTree(nums,0,nums.length);}
}

538. 把二叉搜索树转换为累加树

跳转: 538. 把二叉搜索树转换为累加树

学习: 代码随想录公开讲解

问题:

给出二叉 搜索 树的根节点,该树的节点值各不相同,请你将其转换为累加树(Greater Sum Tree),使每个节点 node 的新值等于原树中大于或等于 node.val 的值之和。

提醒一下,二叉搜索树满足下列约束条件:

  • 节点的左子树仅包含键 小于 节点键的节点。
  • 节点的右子树仅包含键 大于 节点键的节点。
  • 左右子树也必须是二叉搜索树。

在这里插入图片描述

思路:

二叉树搜索树中序遍历有序,这题要把节点替换为大于等于当前节点的累加和,所以可以逆反中序遍历,然后额外使用一个遍历记录上一次的值.

复杂度:

  • 时间复杂度: O ( n ) O(n) O(n)
  • 空间复杂度: O ( 1 ) O(1) O(1)

代码(逆反中序遍历):

class Solution {int pre = 0;public TreeNode convertBST(TreeNode root) {if(root==null) return null;convertBST(root.right);root.val+=pre;pre = root.val;convertBST(root.left);return root;        }
}

2179. 统计数组中好三元组数目(每日一题)

跳转: 2179. 统计数组中好三元组数目

灵茶山艾府题解

问题:

给你两个下标从 0 开始且长度为 n 的整数数组 nums1nums2 ,两者都是 [0, 1, ..., n - 1]排列

好三元组 指的是 3互不相同 的值,且它们在数组 nums1nums2 中出现顺序保持一致。换句话说,如果我们将 pos1v 记为值 vnums1 中出现的位置,pos2v 为值 vnums2 中的位置,那么一个好三元组定义为 0 <= x, y, z <= n - 1 ,且 pos1x < pos1y < pos1zpos2x < pos2y < pos2z 都成立的 (x, y, z)

请你返回好三元组的 总数目

思路:

这题直接做是找公共子序列个数,因为都是 0 到 n-1 的排序 ,所以可以通过映射转化为求递增子序列问题(获得一个索引哈希,另一个顺序枚举中间,看看之前有多少比自己小的合法值,就能算出之后有多少比自己大的合法值)
知道前面合法的 l e s s y less_y lessy,后面合法的就是 n − 1 − y − ( i − l e s s y ) n−1−y−(i−less_y) n1y(ilessy)
合记:在这里插入图片描述

但哪怕使用前缀和,如果直接暴力,也会超时
所以需要使用树状数组这种特殊的数据结构来计算合法前缀和

复杂度:

  • 时间复杂度: O ( n l o g n ) O(nlog_n) O(nlogn)
  • 空间复杂度: O ( n ) O(n) O(n)

代码:

class FenwickTree {private final int[] tree;public FenwickTree(int n) {tree = new int[n + 1]; // 使用下标 1 到 n}// a[i] 增加 val// 1 <= i <= npublic void update(int i, long val) {for (; i < tree.length; i += i & -i) {tree[i] += val;}}// 求前缀和 a[1] + ... + a[i]// 1 <= i <= npublic int pre(int i) {int res = 0;for (; i > 0; i &= i - 1) {res += tree[i];}return res;}
}class Solution {public long goodTriplets(int[] nums1, int[] nums2) {int n = nums1.length;int[] p = new int[n];for (int i = 0; i < n; i++) {p[nums1[i]] = i;}long ans = 0;FenwickTree ft = new FenwickTree(n);for(int i=0;i<n;i++) {int y = p[nums2[i]];long less = ft.pre(y);ans+=less*(n-1-y-i+less);ft.update(y+1,1);}return ans;}
}

307. 区域和检索 - 数组可修改(树状数组)

跳转: 307. 区域和检索 - 数组可修改

学习: 动画讲解讲解

问题:

给你一个数组 nums ,请你完成两类查询。

  1. 其中一类查询要求 更新 数组 nums 下标对应的值
  2. 另一类查询要求返回数组 nums 中索引 left 和索引 right 之间( 包含 )的nums元素的 ,其中 left <= right

实现 NumArray 类:

  • NumArray(int[] nums) 用整数数组 nums 初始化对象
  • void update(int index, int val)nums[index] 的值 更新val
  • int sumRange(int left, int right) 返回数组 nums 中索引 left 和索引 right 之间( 包含 )的nums元素的 (即,nums[left] + nums[left + 1], ..., nums[right]

思路:

lowbit
对于更新操作,通过索引可以定位到其对应的最底层,然后直接向上修改即可.上层在后面,每次向上刚好是加上bit最左位 lowbit.
查询操作也是先定位底层,不过是要加前缀,所以每次向上是减去bit最左位 lowbit.

复杂度:

  • 时间复杂度: O ( n ) O(n) O(n)
  • 空间复杂度: O ( n ) O(n) O(n)

代码:

class NumArray {private final int[] tree;private final int[] nums;public NumArray(int[] nums) {int n= nums.length;this.nums = nums;tree = new int[n+1];for(int i=1;i<=n;i++){tree[i]+=nums[i-1];int nxt = i+(i&-i);if(nxt<=n) tree[nxt] += tree[i];}}public void update(int index, int val) {int delta = val - nums[index];nums[index] = val;for(int i=index+1;i<tree.length;i+=i&-i){tree[i] += delta;}}private int prefixSum(int i) {int s = 0;for (; i > 0; i &= i - 1) { // i -= i & -i 的另一种写法s += tree[i];}return s;}public int sumRange(int left, int right) {return prefixSum(right+1)-prefixSum(left);}
}

122. 买卖股票的最佳时机 II

跳转: 122. 买卖股票的最佳时机 II

学习: 灵茶山艾府题解 & 公开讲解

问题:

给你一个整数数组 prices ,其中 prices[i] 表示某支股票第 i 天的价格。

在每一天,你可以决定是否购买和/或出售股票。你在任何时候 最多 只能持有 一股 股票。你也可以先购买,然后在 同一天 出售。

返回 你能获得的 最大 利润

思路:

可以考虑股票持有和未持有两种状态,每种状态都可以基于前一天持有或未持有变化而来
这题如果递归必须要加记忆化搜索

复杂度:

  • 时间复杂度: O ( n ) O(n) O(n)
  • 空间复杂度: O ( 1 ) O(1) O(1)

代码(递推):

class Solution {public int maxProfit(int[] prices) {int n = prices.length;int p1 = 0;int p2 = Integer.MIN_VALUE;for(int i=1;i<n;i++){int tmp = p1;p2 = Math.max(p1-prices[i-1],p2);p1 = Math.max(p2+prices[i-1],tmp);// System.out.println(p1+" "+p2);}return Math.max(p2+prices[n-1],p1);}
}

复杂度:

  • 时间复杂度: O ( n ) O(n) O(n)
  • 空间复杂度: O ( n ) O(n) O(n)

代码(递归):

class Solution {private int[][] memo;public int dfs(int[] prices,int day,int choose){if(day==0){return choose==1?-100000:0;} if(memo[day][choose]!=-1)return memo[day][choose];int a = dfs(prices,day-1,0);int b = dfs(prices,day-1,1);if(choose==1){return memo[day][1] =  Math.max(a-prices[day-1],b);}else{return memo[day][0] = Math.max(b+prices[day-1],a);}}public int maxProfit(int[] prices) {int n = prices.length;memo = new int[n+1][2];for(int[] row:memo){Arrays.fill(row,-1);}return dfs(prices,n,0);}
}

309. 买卖股票的最佳时机含冷冻期

跳转: 309. 买卖股票的最佳时机含冷冻期

学习: 灵茶山艾府题解 & 公开讲解

问题:

给定一个整数数组prices,其中第 prices[i] 表示第 *i* 天的股票价格 。

设计一个算法计算出最大利润。在满足以下约束条件下,你可以尽可能地完成更多的交易(多次买卖一支股票):

  • 卖出股票后,你无法在第二天买入股票 (即冷冻期为 1 天)。

**注意:**你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。

思路:

可以考虑股票持有和未持有两种状态,每种状态都可以基于前一天持有或未持有变化而来
这题如果递归必须要加记忆化搜索
这题就是比上题多个冷冻期,考虑买入时不能是刚卖出即可

如果写递推,因为设计前天,需要三个变量

复杂度:

  • 时间复杂度: O ( n ) O(n) O(n)
  • 空间复杂度: O ( 1 ) O(1) O(1)

代码(递推):

class Solution {public int maxProfit(int[] prices) {int n = prices.length;int p1 = 0;int pre_p1 = 0;int p2 = Integer.MIN_VALUE;for(int i=0;i<n;i++){int tmp = p1;p2 = Math.max(pre_p1-prices[i],p2);p1 = Math.max(p2+prices[i],tmp);pre_p1 = tmp;// System.out.println(p1+" "+p2);}return p1;}
}

复杂度:

  • 时间复杂度: O ( n ) O(n) O(n)
  • 空间复杂度: O ( n ) O(n) O(n)

代码(递归):

class Solution {private int[][] memo;public int dfs(int[] prices, int day, int choose) {if (day < 0) {return choose == 1 ? -100000 : 0;}if (memo[day][choose] != -1)return memo[day][choose];if (choose == 1) {return memo[day][1] = Math.max(dfs(prices, day - 2, 0) - prices[day], dfs(prices, day - 1, 1));}return memo[day][0] = Math.max(dfs(prices, day - 1, 1) + prices[day], dfs(prices, day - 1, 0));}public int maxProfit(int[] prices) {int n = prices.length;memo = new int[n+1][2];for (int[] row : memo) {Arrays.fill(row, -1);}return dfs(prices, n-1, 0);}
}

188. 买卖股票的最佳时机 IV

跳转: 188. 买卖股票的最佳时机 IV

学习: 灵茶山艾府题解 & 公开讲解

问题:

给你一个整数数组 prices 和一个整数 k ,其中 prices[i] 是某支给定的股票在第 i 天的价格。

设计一个算法来计算你所能获取的最大利润。你最多可以完成 k 笔交易。也就是说,你最多可以买 k 次,卖 k 次。

**注意:**你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。

思路:

可以考虑股票持有和未持有两种状态,每种状态都可以基于前一天持有或未持有变化而来
这题如果递归必须要加记忆化搜索
这题限制交易次数,所以需要额外加一维状态标识

复杂度:

  • 时间复杂度: O ( n ) O(n) O(n)
  • 空间复杂度: O ( 1 ) O(1) O(1)

代码(迭代):

class Solution {public int maxProfit(int k, int[] prices) {int[][] f = new int[k + 2][2];for (int j = 0; j <= k + 1; j++) {f[j][1] = Integer.MIN_VALUE / 2;}for (int p : prices) {for (int i=k+1;i>0;i--) {f[i][1] = Math.max(f[i][0] - p, f[i][1]);f[i][0] = Math.max(f[i-1][1] + p, f[i][0]);// System.out.println(p1+" "+p2);}}return f[k+1][0];}
}

复杂度:

  • 时间复杂度: O ( n ) O(n) O(n)
  • 空间复杂度: O ( n ) O(n) O(n)

代码(递归):

class Solution {private int[][][] memo;public int dfs(int[] prices, int day, int choose,int k) {if(k<0) return -100000;if (day < 0) {return choose == 1 ? -100000 : 0;}if (memo[day][k][choose] != -1)return memo[day][k][choose];if (choose == 1) {return memo[day][k][1] = Math.max(dfs(prices, day - 1, 0,k) - prices[day], dfs(prices, day - 1, 1,k));}return memo[day][k][0] = Math.max(dfs(prices, day - 1, 1,k-1) + prices[day], dfs(prices, day - 1, 0,k));}public int maxProfit(int k, int[] prices) {int n = prices.length;memo = new int[n][k+1][2];for (int[][] row : memo) {for(int[] row2 : row)Arrays.fill(row2, -1);}return dfs(prices, n-1, 0,k);}
}

总结

今天继续练习二叉树,复习了平衡二叉树和累加树
了解了树状数组和状态机动规的思路

往期打卡

代码随想录算法训练营第十七天

代码随想录算法训练营周末三

代码随想录算法训练营第十六天

代码随想录算法训练营第十五天

代码随想录算法训练营第十四天

代码随想录算法训练营第十三天

代码随想录算法训练营第十二天

代码随想录算法训练营第十一天

代码随想录算法训练营周末二

代码随想录算法训练营第十天

代码随想录算法训练营第九天

代码随想录算法训练营第八天

代码随想录算法训练营第七天

代码随想录算法训练营第六天

代码随想录算法训练营第五天

代码随想录算法训练营周末一

代码随想录算法训练营第四天

代码随想录算法训练营第三天

代码随想录算法训练营第二天

代码随想录算法训练营第一天

http://www.dtcms.com/wzjs/191098.html

相关文章:

  • 陕西有没有做网站普查公司上海企业网站推广
  • 万网租空间 网站手机百度网页版 入口
  • 做企业网站流程上海排名优化seobwyseo
  • 镇江网站建设流程seo排名哪家正规
  • 智慧旅游网站建设中国seo关键词优化工具
  • 穹拓网站建设怎么做一个网页
  • 怎么做网站web知乎推广
  • 如何查看一个网站是用什么程序做的免费自助建站哪个最好
  • 网站建设流程步骤怎么样太原最新情况
  • wordpress 作者名称济南seo怎么优化
  • 网站公网安备链接怎么做东莞整站优化排名
  • 做网站的第一步可以看国外网站的浏览app
  • 来宾北京网站建设企业网站的作用和意义
  • seo点石论坛seo优化是怎么回事呢
  • 自己网站建设多少钱百度搜索风云榜排名
  • 宝安营销型网站制作天津做网站的网络公司
  • 衡阳做网站关键词竞价排名是什么意思
  • 网站内链设置百度权重域名
  • 东莞大岭山建网站公司深圳网站seo服务
  • 有什么网站做统计图的小程序开发公司
  • 网站续费公司海外互联网推广平台
  • 网站代码500长尾关键词挖掘词
  • 阿克苏网站建设咨询百度seo关键词排名s
  • 义乌网站建设联系方式地推接单平台找推网
  • .net域名可以做银行网站吗网站收录怎么弄
  • 在哪里能找到建网站网络营销客服主要做什么
  • 静安做网站百度关键字搜索量查询
  • 全渠道分销零售平台宁波网站推广优化公司怎么样
  • 换域名影响网站不百度竞价推广方案范文
  • 旅行社网站建设方案书处理事件seo软件