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

地方门户网站开发seo排名点击首页

地方门户网站开发,seo排名点击首页,静态网页的制作,中国做的比较好的网站设计公司有哪些(优先整理热门100及面试150,不定期持续更新,欢迎关注) 322. 零钱兑换 给你一个整数数组 coins ,表示不同面额的硬币;以及一个整数 amount ,表示总金额。 计算并返回可以凑成总金额所需的最少的硬币个数。如果没有任何…

(优先整理热门100及面试150,不定期持续更新,欢迎关注)


322. 零钱兑换

给你一个整数数组 coins ,表示不同面额的硬币;以及一个整数 amount ,表示总金额。
计算并返回可以凑成总金额所需的最少的硬币个数。如果没有任何一种硬币组合能组成总金额,返回 -1
你可以认为每种硬币的数量是无限的。

示例 1:

输入:coins = [1, 2, 5], amount = 11
输出:3 

解释:11 = 5 + 5 + 1

示例 2:

输入:coins = [2], amount = 3
输出:-1

示例 3:

输入:coins = [1], amount = 0
输出:0

提示:

  • 1 <= coins.length <= 12
  • 1 <= coins[i] <= 2^31 - 1
  • 0 <= amount <= 10^4

方法一:动态规划

使用动态规划数组 dp,其中 dp[i] 表示凑成金额 i 所需的最少硬币个数。通过逐步填充 dp 数组,最终得到 dp[amount] 的结果。

  1. 初始化

    • dp[0] = 0:金额为0时不需要任何硬币。
    • 其他金额初始化为 amount + 1,因为最多需要 amount 个硬币(全用面额1的硬币),初始值设为更大的数表示暂时不可达。
  2. 状态转移

    • 对于每个金额 i,遍历所有硬币面额 coin
    • coin ≤ i,则可以通过 i - coin 的金额加上当前硬币组成 i,即 dp[i] = min(dp[i], dp[i - coin] + 1)
  3. 结果判断

    • 如果最终 dp[amount] 仍大于 amount,说明无法凑出目标金额,返回 -1
    • 否则返回 dp[amount],即最少硬币数。

代码实现(Java)

import java.util.Arrays;class Solution {public int coinChange(int[] coins, int amount) {if (amount == 0) {return 0;}int[] dp = new int[amount + 1];Arrays.fill(dp, amount + 1); // 初始化为一个较大的值(超过最大可能硬币数)dp[0] = 0; // 金额0需要0个硬币// 遍历所有金额,从1到amountfor (int i = 1; i <= amount; i++) {// 遍历所有硬币面额for (int coin : coins) {if (coin <= i) { // 硬币面额不超过当前金额时,才可能使用dp[i] = Math.min(dp[i], dp[i - coin] + 1);}}}// 判断结果是否有效return dp[amount] > amount ? -1 : dp[amount];}
}

方法二:BFS解法

将问题转化为图的最短路径问题,其中每个节点表示当前剩余金额,边表示使用一枚硬币。BFS按层遍历,首次到达金额0时的层数即为最少硬币数。

  1. 初始化

    • 队列存放待处理的金额,初始为 amount
    • 已访问集合 visited 防止重复处理相同金额。
    • steps 记录当前层数(即已用硬币数)。
  2. 层序遍历

    • 每层开始前记录队列大小,处理完该层所有节点后步数+1。
    • 对每个金额尝试所有硬币:
      • current - coin == 0,直接返回当前步数。
      • 若新金额合法且未访问过,加入队列并标记,避免重复处理相同金额。
  3. 终止条件

    • 队列清空时仍未找到解,返回 -1

代码实现(Java)

import java.util.*;class Solution {public int coinChange(int[] coins, int amount) {if (amount == 0) return 0;Queue<Integer> queue = new LinkedList<>();Set<Integer> visited = new HashSet<>();queue.offer(amount);visited.add(amount);int steps = 0;while (!queue.isEmpty()) {int size = queue.size();steps++;for (int i = 0; i < size; i++) {int current = queue.poll();for (int coin : coins) {int next = current - coin;if (next == 0) {return steps; // 找到解,直接返回}if (next > 0 && !visited.contains(next)) {visited.add(next);queue.offer(next);}}}}return -1; // 队列清空仍未找到解}
}

复杂度分析

  • 动态规划时间复杂度:外层循环:O(amount),内层循环:O(coins.length),总复杂度:O(amount * coins.length)
  • BFS时间复杂度:最坏情况:O(amount * coins.length),实际效率取决于硬币面额分布,大额硬币可能加速收敛。

对比总结

方法优势劣势
BFS无需预计算所有状态,快速收敛空间复杂度高(队列膨胀)
动态规划适合多次查询,空间可控需遍历全部状态

347. 前 K 个高频元素

给你一个整数数组 nums 和一个整数 k ,请你返回其中出现频率前 k 高的元素。你可以按任意顺序返回答案。

示例 1:

输入: nums = [1,1,1,2,2,3], k = 2
输出: [1,2]

示例 2:

输入: nums = [1], k = 1
输出: [1]

提示:

  • 1 <= nums.length <= 105
  • k 的取值范围是 [1, 数组中不相同的元素的个数]
  • 题目数据保证答案唯一,换句话说,数组中前 k 个高频元素的集合是唯一的

进阶: 你所设计算法的时间复杂度必须优于 O(n log n) ,其中 n 是数组大小。

方法一:最小堆(优先队列)

使用最小堆维护当前频率最高的k个元素,遍历时保持堆的大小不超过k,时间复杂度为O(n log k)

  1. 统计频率:使用哈希表记录每个元素的出现次数。
  2. 维护最小堆:将元素按频率加入堆,堆大小超过k时移除堆顶(最小频率元素)。
  3. 提取结果:堆中剩余的元素即为前k高的频率元素。

代码实现(Java)

class Solution {public int[] topKFrequent(int[] nums, int k) {// 统计频率Map<Integer, Integer> freqMap = new HashMap<>();for (int num : nums) {freqMap.put(num, freqMap.getOrDefault(num, 0) + 1);}// 创建最小堆,按频率升序排序PriorityQueue<Map.Entry<Integer, Integer>> heap = new PriorityQueue<>((a, b) -> a.getValue() - b.getValue());// 维护堆的大小为kfor (Map.Entry<Integer, Integer> entry : freqMap.entrySet()) {heap.offer(entry);if (heap.size() > k) {heap.poll();}}// 提取结果int[] res = new int[k];int idx = 0;while (!heap.isEmpty()) {res[idx++] = heap.poll().getKey();}return res;}
}

方法二:桶排序

基于频率的桶排序,时间复杂度为O(n),适合处理大数据量。

  1. 统计频率:记录每个元素出现的次数及最大频率。
  2. 构建频率桶:将元素按频率存入对应桶中。
  3. 逆序收集结果:从高频率到低频率遍历桶,收集前k个元素。

代码实现(Java)

class Solution {public int[] topKFrequent(int[] nums, int k) {// 统计频率Map<Integer, Integer> freqMap = new HashMap<>();for (int num : nums) {freqMap.put(num, freqMap.getOrDefault(num, 0) + 1);}// 创建桶数组List<Integer>[] bucket = new List[nums.length + 1];for (Map.Entry<Integer, Integer> entry : freqMap.entrySet()) {int freq = entry.getValue();if (bucket[freq] == null) {bucket[freq] = new ArrayList<>();}bucket[freq].add(entry.getKey());}// 收集结果int[] res = new int[k];int idx = 0;for (int i = bucket.length - 1; i >= 0 && idx < k; i--) {if (bucket[i] != null) {for (int num : bucket[i]) {res[idx++] = num;if (idx == k) break;}}}return res;}
}

复杂度分析

1、最小堆

  • 时间复杂度:O(n log k),其中n为数组长度,k为结果数量。
    空间复杂度:O(n),哈希表和堆的空间。
  • 优点:空间占用相对较低,适合k较小的情况。
    缺点:当k接近n时,时间复杂度接近O(n log n)

2、桶排序

  • 时间复杂度:O(n),所有操作均为线性时间。
    空间复杂度:O(n),桶数组和哈希表的空间。
  • 优点:时间复杂度严格为O(n),适合大数据量。
    缺点:需要额外空间存储桶,最大频率较高时空间占用大。

394. 字符串解码

给定一个经过编码的字符串,返回它解码后的字符串。
编码规则为: k[encoded_string],表示其中方括号内部的 encoded_string 正好重复 k 次。注意 k 保证为正整数。
你可以认为输入字符串总是有效的;输入字符串中没有额外的空格,且输入的方括号总是符合格式要求的。
此外,你可以认为原始数据不包含数字,所有的数字只表示重复的次数 k ,例如不会出现像 3a2[4] 的输入。

示例 1:

输入:s = "3[a]2[bc]"
输出:"aaabcbc"

示例 2:

输入:s = "3[a2[c]]"
输出:"accaccacc"

示例 3:

输入:s = "2[abc]3[cd]ef"
输出:"abcabccdcdcdef"

示例 4:

输入:s = "abc3[cd]xyz"
输出:"abccdcdcdxyz"

提示:

  • 1 <= s.length <= 30
  • s 由小写英文字母、数字和方括号 '[]' 组成
  • s 保证是一个有效的输入
  • s 中所有整数的取值范围为 [1, 300]

方法:栈辅助法

利用栈来处理嵌套的括号结构,保存每层括号外的字符串和重复次数。遍历字符串时解析数字,遇到左括号时将当前状态压栈,遇到右括号时弹出栈顶元素进行字符串拼接。

  1. 初始化栈和变量:使用两个栈分别保存当前层的字符串和重复次数,当前字符串和数字变量记录正在处理的部分。
  2. 遍历字符
    • 数字:累加计算多位数。
    • 左括号:压栈当前字符串和数字,重置变量。
    • 右括号:弹出栈顶的字符串和数字,将当前字符串重复后拼接。
    • 字母:直接追加到当前字符串。
  3. 返回结果:最终拼接完成的字符串即为答案。

代码实现(Java)

class Solution {public String decodeString(String s) {Stack<Integer> numStack = new Stack<>();Stack<StringBuilder> strStack = new Stack<>();StringBuilder currentStr = new StringBuilder();int num = 0;for (char c : s.toCharArray()) {if (Character.isDigit(c)) {num = num * 10 + (c - '0');} else if (c == '[') {strStack.push(currentStr);numStack.push(num);currentStr = new StringBuilder();num = 0;} else if (c == ']') {int k = numStack.pop();StringBuilder prevStr = strStack.pop();String temp = currentStr.toString();prevStr.append(temp.repeat(k));currentStr = prevStr;} else {currentStr.append(c);}}return currentStr.toString();}
}

复杂度分析

  • 时间复杂度O(n × m),其中n是字符串长度,m是最大重复次数。每个字符处理一次,字符串拼接的时间取决于重复次数。
  • 空间复杂度O(n),栈的深度最坏情况下与字符串长度成线性关系。

博客源文件Gitee仓库:

gitee.com/richardmilos/allen-csdn-notes

(持续更新,未完待续)

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

相关文章:

  • 青岛高新区建设局网站seo线下培训课程
  • 网站开发 旅游最新全国疫情实时大数据
  • 新手怎么做html5网站体验营销是什么
  • 分析不同网站的优缺点湖南网站设计外包服务
  • 专业做网站哪里有杭州网站设计制作
  • 百度做的网站 后台管理怎么进入优化设计高中
  • 网页编成网站东营百度推广电话
  • 深圳做网站个人seo实战密码电子书
  • 免备案网站建站指数型基金是什么意思
  • 机械网站建设比较好的青岛seo建站
  • 如何用php做电商网站seo教程技术资源
  • 西海岸建设局网站东莞网站seo公司
  • 国外建站用什么最多网页广告调词平台多少钱
  • 公司网站开发费用记入什么科止友链网
  • 安阳 网站建设南宁seo外包服务
  • 学校网站建设的建议seo每日工作内容
  • 老司机资源免费观看福州外包seo公司
  • 国外做名片的网站湖南网络优化
  • 中国企业500强排名一览表整站seo技术搜索引擎优化
  • 网站后台 二级域名手机优化
  • 时时彩网站做制作成都网络推广优化
  • 赤峰网站建设培训it培训机构学费一般多少
  • 网站代理加盟搜索引擎优化的五个方面
  • 做网站设计网站建设推广seo网站优化培训
  • 进不了建设银行网站网站统计分析工具
  • 呼市做网站公司千锋教育课程
  • icp ip 网站备案查询百度一下首页官网百度
  • 西藏阿里地区建设局网站seo sem是什么意思
  • 佛山企业网站制作关键词抓取工具都有哪些
  • 国内的网站空间电子营销主要做什么