/秋招突击——7/21——复习{堆——数组中的第K大元素}——新作{回溯——全排列、子集、电话号码的字母组合、组合总和}

文章目录

    • 引言
    • 复习
      • 数组中的第K大的最大元素
        • 复习实现
        • 参考实现
    • 新作
      • 46 全排列
      • 个人实现
        • 参考实现
      • 子集
        • 个人实现
        • 参考实现
      • 电话号码的字母组合
        • 复习实现
      • 组合总和
      • 个人实现
        • 参考实现
    • 总结

引言

  • 昨天的科大讯飞笔试做的稀烂,今天回来好好练习一下,主要是针对下述两种题型,分别是对顶堆还有回溯,对顶堆的题目并不多,主要是回溯。下次再遇到这种题目,直接背模板,然后开始做!

复习

数组中的第K大的最大元素

  • 题目链接

  • 第一次做

  • 第二次做

  • 不知不觉已经是第三次做了,感觉还是有点懵,O(N)的时间复杂度,说明可以遍历多次,但是不能嵌套遍历!想想看哈

复习实现
  • 我还是会使用堆实现,并且发现了如果第一次不会做,那么后续会一直不会做,记不住!这里还是要总结.
  • 这里还是使用了堆排序时间,虽然时间复杂度不满足要求,但是单纯为了练习一下!
class Solution {public int findKthLargest(int[] nums, int k) {//define m is lenght ,and pq to sort the numint m = nums.length;Queue<Integer> pq = new PriorityQueue<>();// traverse the numsfor(int i = 0;i < m;i ++){if(pq.size() < k)   pq.add(nums[i]);else{if(nums[i] > pq.peek()){pq.poll();pq.add(nums[i]);}}}return pq.peek();}
}

在这里插入图片描述

参考实现
  • 这里正确的做法是使用快排进行修改,这里先回顾一下快排的模板
void quickSort(nums q,int l ,int r){if(l >= r) return;int i = l - 1,j = r + 1,x = q[(l + r)>>1];while(i< j){do i ++ ;while(q[i] < x);do j ++ ;while(q[j] > x);if(i < j) swap(q[i],q[j]);}quickSort(q,l,j),quickSort(q,j + 1,r);
}
  • 这样背!虽然很蹩脚,但是能记住就行了,记住了就好些了!
    • 左右相交就返回
    • 左左右右是 ij
    • i加小 j减大
    • i小j大做交换
    • j做划分两边排

这里是要求第K大的数字,所以得改变一下i和j交换的方向,最后的序列应该是从大到小,然后再是找第k大的元素,这道题是记住了!修改的话,就从最后的终止条件开始!

具体实现

class Solution {public int quickSort(int[] nums,int l ,int r,int k){if(l == r)  return nums[k];int i = l - 1,j = r + 1,x = nums[(l + r) >> 1];while(i < j){do i ++;while(nums[i] > x);do j --;while(nums[j] < x);if(i < j) {int temp = nums[i];nums[i] = nums[j];nums[j] = temp;}}if(j >= k)   return quickSort(nums,l,j,k);else return quickSort(nums,j + 1,r,k);}public int findKthLargest(int[] nums, int k) {//define m is lenght ,and pq to sort the numint m = nums.length;// traverse the numsint x = quickSort(nums,0,m - 1,k - 1 );return x;}
}

在这里插入图片描述

新作

46 全排列

  • 题目链接
    在这里插入图片描述
    注意
  • 所有整数互不相同,不用处理特殊情况。
  • 数组的长度会出现的一的情况,边界情况,需要特殊处理!

个人实现

  • 标准回溯,确定一个模板直接开始写。
    • 终止条件:idx = 0,并将结果加入到res中
    • 迭代条件:遍历剩余的元素,随机加入到临时列表中
class Solution {public List<List<Integer>> res = new ArrayList<>();void dfs(int[] nums,int idx,List<Integer> list,Set<Integer> set){if(idx == 0){res.add(new ArrayList(list));return;}// iterator conditionfor(int i = 0;i < nums.length;i ++){int x = nums[i];if(!set.contains(x)){list.add(x);set.add(x);dfs(nums,idx - 1,list,set);list.remove(list.size() - 1);set.remove(x);}}}public List<List<Integer>> permute(int[] nums) {List<Integer> list = new ArrayList<>();Set<Integer> set = new HashSet<>();dfs(nums,nums.length,list,set);return res;}
}

觉得写的有点繁琐,看看参考的教程是怎么写的

  • 注意,在Java中res.add方法是引用传递,需要创建一个同元素变量的副本才行,不然会越界!
参考实现
  • 明确需要记录的状态

    • 每一个位置具体的位置保存的数字,也就是list
    • 每一个数字的使用情况,使用set
    • 递归到了第几步
  • 他是使用全局变量来声明,没有使用形参传递对应

这里就不写了,基本上都是一致的

子集

  • 题目链接
    在这里插入图片描述
    注意
  • 存在数组为1的特殊情况,可能需要特殊处理
  • 各个元素互不相同
  • 元素有负数的情况
个人实现
  • 刚才那道题目是所有的排列情况,这道题目是所有的组合情况,应该也可以使用回溯实现。这个和刚才相同,不过是在每一次的改变环境的时候,就将结果进行保存!
class Solution {List<Integer> list = new ArrayList<>();Set<Integer> set = new HashSet<>();Set<List<Integer>> res = new HashSet<>();void dfs(int[] nums,int idx){if(idx == nums.length){List<Integer> temp = new ArrayList<>(list);Collections.sort(temp);res.add(temp);}for(int i = 0;i < nums.length;i ++){int x = nums[i];if(!set.contains(x)){set.add(x);list.add(x);List<Integer> temp = new ArrayList<>(list);Collections.sort(temp);res.add(temp);dfs(nums,idx + 1);set.remove(x);list.remove(list.size() - 1);}}}public List<List<Integer>> subsets(int[] nums) {res.add(Arrays.asList());dfs(nums,0);List<List<Integer>> resList = new ArrayList<>();for(List<Integer> x:res){resList.add(x);}return resList;}
}

在这里插入图片描述

上面这样做就不对,得再想想,如果是回溯的话,得更新一下状态的改变,不能直愣愣的添加对应的元素!出来结果了,然后再添加!

  • 好蠢呀,没想到,没想到,既然没想到,记下来,下次肯定能够想到!
参考实现

方法一、DFS
递归的条件

  • 每一个元素只有两种情况,放或者不放,所以遍历这两种情况就行了!
class Solution {List<Integer> list = new ArrayList<>();List<List<Integer>> res = new ArrayList<>();void dfs(int[] nums,int idx){// termiante conditionif(idx == nums.length){res.add(new ArrayList(list));return ;}// traverse all the condition// get  the idx numlist.add(nums[idx]);dfs(nums,idx + 1);list.remove(list.size() - 1);// do not get the idx numdfs(nums,idx + 1);}public List<List<Integer>> subsets(int[] nums) {dfs(nums,0);return res;}
}

在这里插入图片描述

方法二、位运算

  • 将这个问题转化为对应的二进制表示,每一个物体只有放或者不放两种情况,对应就是不同的二进制数,而且全排列的最终结果数量就是 2 n 2^n 2n

具体实现如下
这里刚好练习一下Java中的二进制数是怎么操作的!

class Solution {public List<List<Integer>> subsets(int[] nums) {List<List<Integer>> res = new ArrayList<>();int n = nums.length;// traverse all the binary numfor(int i = 0;i < (1 << n);i ++){List<Integer> temp = new ArrayList<>();for(int j = 0;j < n;j ++){// judge the j is 0 or 1if(((i >> j) & 1) == 1){temp.add(nums[j]);}}res.add(temp);}return res;}
}

电话号码的字母组合

  • 题目链接
  • 第一次做
复习实现
class Solution {Map<Character,List<Character>> map = new HashMap<>();StringBuilder str = new StringBuilder();List<String> res = new ArrayList<>();void dfs(String digits,int idx){if(idx == digits.length()){//System.out.println(str.toString());res.add(str.toString());return;}for(char x:map.get(digits.charAt(idx))){str.append(x);dfs(digits,idx + 1);str.deleteCharAt(str.length() - 1);}}public List<String> letterCombinations(String d) {map.put('2',Arrays.asList('a','b','c'));map.put('3',Arrays.asList('d','e','f'));map.put('4',Arrays.asList('g','h','i'));map.put('5',Arrays.asList('j','k','l'));map.put('6',Arrays.asList('m','n','o'));map.put('7',Arrays.asList('p','q','r','s'));map.put('8',Arrays.asList('t','u','v'));map.put('9',Arrays.asList('w','x','y','z'));    if(d.length() == 0) return res;dfs(d,0);return res;}
}

在这里插入图片描述

  • 没以前使用C++实现起来那么快,写起来也没有那么方便!

组合总和

  • 题目链接
    在这里插入图片描述
    注意
  • 所有元素互不相同
  • 每一个元素可以放很多次

个人实现

  • 这题可以使用两种方式实现
    • 完全背包问题,不过需要记录对应的背包状态,时间复杂度比较低,但是不知道怎么记录满足条件的状态
      • 随便选一个,装满为止;F-V,加上价值,这里价值为零
    • 暴力回溯,时间复杂度高

暴力回溯

class Solution {List<Integer> list = new ArrayList<>();List<List<Integer>> resList = new ArrayList<>();Set<List<Integer>> res = new HashSet<>();// brute dfs to solve the problemvoid dfs(int[] candi,int tar,int temp){if(temp == tar){List<Integer> tempList = new ArrayList(list);Collections.sort(tempList);res.add(tempList);return;}for(int i = 0;i < candi.length;i ++){if(temp + candi[i] <= tar){// put//System.out.println(candi[i]);list.add(candi[i]);dfs(candi,tar,temp + candi[i]);list.remove(list.size() - 1);}}}public List<List<Integer>> combinationSum(int[] candidates, int target) {dfs(candidates,target,0);for(List<Integer> x:res){resList.add(x);}return resList;}
}

在这里插入图片描述
我靠,这个居然能过,也是离谱了!

完全背包问题

class Solution {List<Integer> list = new ArrayList<>();List<List<Integer>> resList = new ArrayList<>();public List<List<Integer>> combinationSum(int[] candidates, int target) {int[] f = new int[target + 1];f[0] = 1;for(int i = 0;i < candidates;i ++){for(int j = candidates[i];j < target;j ++){f[j] = f[j] + f[j - candidates[i]];}}return f[target - 1];}
}
  • 这里只能写成这样,因为我并不知道怎么保存中间状态!

不能用完全背包,完全背包并不能获取中间状态!!

参考实现
  • 只能说我对于的回溯的理解还是不够深刻,两种存放方式
    • 是否放当前的数字,要用深度u控制,防止出现死循环
    • 当前物体一定要放,但是顺序不同,需要set控制是否出现
class Solution {List<Integer> list = new ArrayList<>();List<List<Integer>> resList = new ArrayList<>();void dfs(int[] candidates,int dpt,int tar){if(tar == 0){resList.add(new ArrayList(list));return;}if(dpt == candidates.length)    return;for(int i = 0;i * candidates[dpt] <= tar ;i ++){dfs(candidates,dpt + 1,tar - i * candidates[dpt]);list.add(candidates[dpt]);}    for(int i = 0; i * candidates[dpt] <= tar ;i ++)list.remove(list.size() - 1);}public List<List<Integer>> combinationSum(int[] candidates, int target) {dfs(candidates,0,target);return resList;}
}

在这里插入图片描述
实现起来确实更优!如果放或者不放,还是需要使用的深度进行控制!
无论怎么样,都需要加上的对应idx控制

总结

  • 今天这几道题做完了,算是对于深度有了更加深刻的认识,主要是控制的遍历的内容,然后每一层迭代控制的始终是idx,然后需要额外的条件进行控制和判定!
  • 写回溯,还是比写其他算法要轻松很多!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/380902.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

GIS技能大赛解题过程(1)

试题要求&#xff1a;制作一幅广西区域发展布局示意图&#xff0c;最终成图参考如下。 做题步骤 一、创建数据库&#xff0c;整合数据入库 要求&#xff1a; 【解题步骤】 1、新建数据库命名为中间数据库.gdb&#xff0c;右键点击【export】导入数据&#xff0c;可以将数据拖…

单链表算法 - 链表分割

链表分割_牛客题霸_牛客网现有一链表的头指针 ListNode* pHead&#xff0c;给一定值x&#xff0c;编写一段代码将所有小于x的。题目来自【牛客题霸】https://www.nowcoder.com/practice/0e27e0b064de4eacac178676ef9c9d70思路: 代码: /* struct ListNode {int val;struct List…

防火墙--内容安全

目录 概述 IAE引擎流程 DPI深度包检测 基于特征字的检测技术 基于应用网关的检测技术 基于行为模式的检测技术 DFI深度流检测 基于数据流进行识别检测的技术 DPI和DFI对比 IDS&#xff08;入侵检测&#xff09; IPS&#xff08;入侵防御&#xff09; 优势 入侵检测…

JVM之经典垃圾回收器

1.垃圾回收器的分类 处理范围划分&#xff1a; 新生代垃圾回收器&#xff1a;serial、parNew、parallel scavenge&#xff1b; 老年代垃圾回收器&#xff1a;serial Old、parallel Old、CMS&#xff1b; 整堆收集器&#xff1a;G1、ZGC&#xff1b; 2.Serial GC Serial是单…

数据结构——线性表(循环链表)

一、循环链表定义 将单链表中终端结点的指针端由空指针改为指向头结点&#xff0c;就使整个单链表形成一 个环&#xff0c;这种头尾相接的单链表称为单循环链表&#xff0c;简称循环链表(circular linked list)。 循环链表解决了一个很麻烦的问题。如何从当中一 个结点出发&am…

STM32测测速---编码电机读取速度的计算

1、首先先了解一下计算的公式 速度计算&#xff1a; 轮胎每转一圈的脉冲数取决于编码器的分辨率&#xff0c;可由下面公式进行计算&#xff1a; PPR是电机的线数 以GA25-370电机为例。 图片来源&#xff1a;第四节&#xff1a;STM32定时器&#xff08;4.JGA25-370霍尔编码器…

【23】Android高级知识之Window(四) - ThreadedRenderer

一、概述 在上一篇文章中已经讲了setView整个流程中&#xff0c;最开始的addToDisplay和WMS跨进程通信的整个过程做了什么。继文章Android基础知识之Window(二)&#xff0c;这算是另外一个分支了&#xff0c;接着讲分析在performTraversals的三个操作中&#xff0c;最后触发pe…

昇思25天学习打卡营第11天|基于 MindSpore 实现 BERT 对话情绪识别

BERT是一种先进的语言模型&#xff0c;由Google在2018年推出。它通过双向编码器Transformer的Encoder部分&#xff0c;捕捉词语和句子的深层含义。BERT的创新之处在于其预训练方法&#xff0c;特别是Masked Language Model和Next Sentence Prediction&#xff0c;这使得它在问答…

【python 已解决】ImportError: No module named ‘example‘ 详解与解决方案

【python 已解决】ImportError: No module named example 详解与解决方案 在Python编程中&#xff0c;ImportError是一个常见的异常类型&#xff0c;它表明Python解释器无法导入指定的模块。当你看到错误提示“ImportError: No module named ‘example’”时&#xff0c;这意味…

基于Llama Index构建RAG应用(Datawhale AI 夏令营)

前言 Hello&#xff0c;大家好&#xff0c;我是GISer Liu&#x1f601;&#xff0c;一名热爱AI技术的GIS开发者&#xff0c;本文参与活动是2024 DataWhale AI夏令营&#xff1b;&#x1f632; 在本文中作者将通过&#xff1a; Gradio、Streamlit和LlamaIndex介绍 LlamaIndex 构…

jenkins 使用教程

1. 安装最新长期稳定版 2.426.1 Redhat Jenkins Packages sudo wget -O /etc/yum.repos.d/jenkins.repo https://pkg.jenkins.io/redhat-stable/jenkins.repo --no-check-certificate sudo rpm --import https://pkg.jenkins.io/redhat-stable/jenkins.io-2023.key yum insta…

Linux云计算 |【第一阶段】ENGINEER-DAY2

主要内容&#xff1a; 磁盘空间管理fdisk、parted工具、开机自动挂载、文件系统、交换空间 KVM虚拟化 实操前骤&#xff1a; 1&#xff09;添加一块硬盘&#xff08;磁盘&#xff09;&#xff0c;需要关机才能进行操作&#xff0c;点击左下角【添加硬件】 2&#xff09;选择2…

如何成为学习高手

文章收录在网站&#xff1a;http://hardyfish.top/ 文章收录在网站&#xff1a;http://hardyfish.top/ 文章收录在网站&#xff1a;http://hardyfish.top/ 文章收录在网站&#xff1a;http://hardyfish.top/ 所有的学习方式&#xff0c;核心都是动脑加动手。 区别在于如何让…

配置RIPv2的认证

目录 一、配置IP地址、默认网关、启用端口 1. 路由器R1 2. 路由器R2 3. 路由器R3 4. Server1 5. Server2 二、搭建RIPv2网络 1. R1配置RIPv2 2. R2配置RIPv2 3. Server1 ping Server2 4. Server2 ping Server1 三、模拟网络攻击&#xff0c;为R3配置RIPv2 四、在R…

【机器学习】智能驱动未来:机器学习在能源效率提升与环境管理中的创新应用

&#x1f4dd;个人主页&#x1f339;&#xff1a;Eternity._ &#x1f339;&#x1f339;期待您的关注 &#x1f339;&#x1f339; ❀目录 &#x1f50d;1. 引言&#x1f4d2;2. 机器学习能源环境领域的应用潜力&#x1f304;能源效率提升&#x1f3de;️环境管理⛰️具体案例…

Flink History Server配置

目录 问题复现 History Server配置 HADOOP_CLASSPATH配置 History Server配置 问题修复 启动flink集群 启动Histroty Server 问题复现 在bigdata111上执行如下命令开启socket&#xff1a; nc -lk 9999 如图&#xff1a; 在bigdata111上执行如下命令运行flink应用程序 …

【Java】用队列实现栈 力扣

文章目录 题目链接题目描述思路代码 题目链接 225.用队列实现栈 题目描述 思路 一个队列在模拟栈弹出元素的时候只要将队列头部的元素&#xff08;除了最后一个元素外&#xff09; 重新添加到队列尾部&#xff0c;此时再去弹出元素就是栈的顺序了。 代码 class MyStack {Q…

用EXCEL和python 计算马尔可夫链转移矩阵

目录 目标&#xff1a;用EXCEL和python 计算马尔可夫链转移矩阵 1 用EXCEL计算 1.1 马尔可夫链的基本应用 1.2 具体计算 2 用python计算马尔可夫转移矩阵 2.1 py代码 2.2 运行结果 3 上面2者计算结果相同 目标&#xff1a;用EXCEL和python 计算马尔可夫链转移矩阵 1 用…

神经网络模型实现(训练、测试)

目录 一、神经网络骨架&#xff1a;二、卷积操作&#xff1a;三、卷积层&#xff1a;四、池化层&#xff1a;五、激活函数&#xff08;以ReLU为例&#xff09;&#xff1a;六、模型搭建&#xff1a;七、损失函数、梯度下降&#xff1a;八、模型保存与加载&#xff1a;九、模型训…

Leetcode2160. 拆分数位后四位数字的最小和:

问题描述&#xff1a; 给你一个四位 正 整数 num 。请你使用 num 中的 数位 &#xff0c;将 num 拆成两个新的整数 new1 和 new2 。new1 和 new2 中可以有 前导 0 &#xff0c;且 num 中 所有 数位都必须使用。 比方说&#xff0c;给你 num 2932 &#xff0c;你拥有的数位包括…