秋招突击——7/22——复习{堆——前K个高频元素}——新作{回溯——单次搜索、分割回文串。链表——环形链表II,合并两个有序链表}

news2024/11/14 13:22:51

文章目录

    • 引言
    • 复习
      • 堆——前K个高频元素
        • 个人实现
        • 复习实现二
        • 参考实现
    • 新作
      • 单词搜索
        • 个人实现
        • 参考实现
      • 分割回文串
        • 个人实现
        • 参考实现
      • 环形链表II
        • 个人实现
        • 参考实现
      • 两个有序链表
        • 个人实现
    • 总结

引言

  • 又是充满挑战性的一天,继续完成我们的任务吧!继续往下刷,一场面试三个构成:八股、项目和算法,都得抓住!加油
  • 今天复习一下堆,然后把回溯剩下的题目全部做完,然后的继续往下做链表!

复习

  • 对顶堆——数据流的中位数
    • front是大顶堆,back是小顶堆

堆——前K个高频元素

  • 题目链接
  • 第一次练习链接
  • 第二次练习链接
  • 虽然已经做了两次,但是一点都想不起来应该怎么做!
个人实现
  • 这道题可以通过设置不同的数据结构实现,通过key-value改变记录每一个数字出现的频率,然后通过PriorityQueue来实现根据频率进行排序,这样效率就快很多!那么怎么实现自定义排序就很重要!
class Solution {
    class Item implements Comparable<Item>{
        int val;
        int freq;
        Item(int value,int frequency){
            val = value;
            freq = frequency;
        }

        // override the compareTo function
        @Override
        public int compareTo(Item o){
            return Integer.compare( this.freq,o.freq);
        }

    }

    public int[] topKFrequent(int[] nums, int k) {
        // define map to store the key-value item ,priorityqueue to sort the item
        PriorityQueue<Item> pq = new PriorityQueue<>(Comparator.reverseOrder());
        Map<Integer,Item> map = new HashMap<>();

        // traverse all the elements
        for(int x :nums){
            if(map.containsKey(x)){
                Item temp = map.get(x);
                temp.freq = temp.freq + 1;
                System.out.println(map.get(x).freq);
            }else{
                Item temp = new Item(x,1);
                map.put(x,temp);
                pq.add(temp);
            }
        }

        // traverse the front k elements
        int[] res = new int[k];
        //System.out.println(pq.peek().val);
        for(int i = 0;i < k;i ++)
            res[i] = pq.poll().val;
        return res;
    }
}

问题

  • 如何重写对象compare方法
    • 要实现Comparable接口
    • compareTo方法是接受当前类型的变量,进行的比较
    • compareTo方法,返回的是一个int类型的变量
    • 实现comparable接口,需要实现compareTo方法
class Item implements Comparable<Item> {
    int val;
    int freq;

    Item(int value, int frequency) {
        val = value;
        freq = frequency;
    }

    // override the compareTo function
    @Override
    public int compareTo(Item o) {
        return Integer.compare(o.freq, this.freq); // descending order
    }
}

在这里插入图片描述

  • 致命问题!!PriorityQueue并不会自动重新排序!需要每次更新都要插入和删除对应的元素,不然会出问题!

在这里插入图片描述

复习实现二
  • 这里不知道自己着了什么魔,这个题目为啥要想的那么复杂,不就是先统计频率,然后再根据频率进行排序吗?为什么要想那么多!
class Solution {
    class Item implements Comparable<Item>{
        int val;
        int freq;
        Item(int value,int frequency){
            val = value;
            freq = frequency;
        }

        // override the compareTo function
        @Override
        public int compareTo(Item o){
            return Integer.compare( this.freq,o.freq);
        }

    }

    public int[] topKFrequent(int[] nums, int k) {
        // define map to store the key-value item ,priorityqueue to sort the item
        PriorityQueue<Item> pq = new PriorityQueue<>(Comparator.reverseOrder());
        Map<Integer,Item> map = new HashMap<>();

        // traverse all the elements
        for(int x :nums){
            if(map.containsKey(x)){
                Item temp = map.get(x);
                temp.freq = temp.freq + 1;
            }else{
                map.put(x,new Item(x,1));
            }
        }

        // traverse the values int the 
        for(Item x:map.values()){
            pq.add(x);
        }

        // traverse the front k elements
        int[] res = new int[k];
        //System.out.println(pq.peek().val);
        for(int i = 0;i < k;i ++)
            res[i] = pq.poll().val;
        return res;
    }
}

在这里插入图片描述
问题

  • 这里Map的相关方法使用起来还是带有试验的性质,很多方法当时写了就错了,编译器提醒没有这种方法,才知道应该换!这里再复习一遍!
  • 加入元素:
    • put(K key,V value)
    • 如果存在旧值,会将其替换
    • 注意,没有set方法,那是list才有的
  • 获取对应的value
    • get(Object key)
    • 如果不含有对应的key,就返回null
  • 删除对应的元素
    • remove(Object key)
  • 判定是否含有对应的元素
    • containsKey(Obejct key)
    • 是containsKey,contains是Set的方法
  • 判定是否为空
    • isEmpty
    • 不是Empty,每次都写错
  • 获取所有value
    • values
    • 这里是返回所有的values,不是valueset
  • 获取所有的key
    • keySet
    • 不是keys
参考实现

使用计数排序

  • 将所有出现的频次记录在对应的数组中,然后根据索引进行遍历,减少遍历的时间!

这里就不记录了,如果感兴趣,就自己去看!

限定堆使用的大小

  • 如果直接将所有的元素加入到堆中进行排序,需要消耗很多时间,这里只要前K个元素,所以只需要维护一个大小为K的堆就行了!
class Solution {
    class Item implements Comparable<Item>{
        int val;
        int freq;
        Item(int value,int frequency){
            val = value;
            freq = frequency;
        }

        // override the compareTo function
        @Override
        public int compareTo(Item o){
            return Integer.compare( this.freq,o.freq);
        }

    }

    public int[] topKFrequent(int[] nums, int k) {
        // define map to store the key-value item ,priorityqueue to sort the item
        PriorityQueue<Item> pq = new PriorityQueue<>();
        Map<Integer,Item> map = new HashMap<>();

        // traverse all the elements
        for(int x :nums){
            if(map.containsKey(x)){
                Item temp = map.get(x);
                temp.freq = temp.freq + 1;
            }else{
                map.put(x,new Item(x,1));
            }
        }

        // traverse the values int the 
        for(Item x:map.values()){
            if(pq.size() < k)
                pq.add(x);
            else{
                if(pq.peek().freq < x.freq){
                    pq.poll();
                    pq.add(x);
                }
            }
        }

        // traverse the front k elements
        int[] res = new int[k];
        //System.out.println(pq.peek().val);
        for(int i = 0;i < k;i ++)
            res[i] = pq.poll().val;
        return res;
    }
}

在这里插入图片描述

新作

单词搜索

题目链接

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
注意

  • 整个二维矩阵的大小可能是一个单元格,仅仅只有一个字母,可能是边界情况需要特殊处理。
  • 目标单词的长度是遍历的深度,也就是遍历树的高度,然后上下左右是四个方向,是每一层遍历的宽度。
个人实现
  • 这道题是典型的回溯,回溯的要素设定如下
    • idx 界限值是 单词的长度
    • 每一层遍历的宽度是上下左右四个方向
    • 需要维护一个exist数组,标记每一个元素的访问情况。
class Solution {

    // define the global string to store the mid situation
    StringBuilder str = new StringBuilder();
    // exist matrix to store the attendence
    boolean[][] exist ;
    //boolean res = false;
    int[][] step = {{1,0},{0,1},{-1,0},{0,-1}};

    boolean dfs(char[][] board,String word,int idx,int x,int y){
        if(idx == word.length()){
            return true;
        }

        for(int i = 0;i < 4;i ++){
            int xNext = x + step[i][0];
            int yNext = y + step[i][1];
            if(xNext >= 0 && xNext < board.length ){
                if(yNext >= 0 && yNext < board[0].length){
                    if(!exist[xNext][yNext] && board[xNext][yNext] == word.charAt(idx)){
                        exist[xNext][yNext] = true;
                        if(dfs(board,word,idx + 1,xNext,yNext)) return true;
                        exist[xNext][yNext] = false;
                    }
                }
            }
        }
        return false;
    }

    public boolean exist(char[][] board, String word) {
        
        //define row and col of the matrix
        int row = board.length;
        int col = board[0].length;
        exist = new boolean[row][col];

        // traverse the board to find the first char
        for(int i = 0;i < board.length;i ++){
            for(int j = 0;j < board[0].length;j ++){
                if(board[i][j] == word.charAt(0)){
                    //System.out.println("first " + board[i][j]);
                
                    exist[i][j] = true;
                    if(dfs(board,word,1,i,j)) return true;
                    exist[i][j] = false;

                }
            }
        }
        
        return false;

    }
}

在这里插入图片描述
代码量真多,不过还是在规定时间内完成了!

参考实现

这里可以将融合到原来的数组中,通过修改特殊的字符,然后判定当前位置是否已经访问过!

分割回文串

题目链接

在这里插入图片描述
注意

  • 回文串,逆序和顺序都是一样的
  • 仅由小写字母构成,不用担心字母大小写变换
  • 长度是1到16,可能有边界情况需要特殊考虑!
个人实现
  • 这道题是一个组合体,找到所有的组合,然后在判断一下,是否是回文就行了。
  • 总结一下回溯的几个要素
    • 树的深度:总的元素数量
    • 节点的宽度:每一个节点放或者不放两种情况。

错误!!这里审错题目了!是分割字符串,应该然后分割之后每一个字串都是回文

  • 修改一下回溯的几个要素
    • 树的深度:分割的位置,总的元素数减一,每一个元素都有一个分割点
    • 节点的宽度:是否在当前点进行分割
class Solution {
    
    List<String> list = new ArrayList();
    List<List<String>> res = new ArrayList<>();

    boolean judge(String str){
        str = str.trim();
        StringBuilder sb = new StringBuilder(str);
        sb.reverse();
        return str.equals(sb.toString());
    }

    void dfs(StringBuilder s,int idx,int len){
        if(idx == len ){
            if(judge(s.toString())){
                list.add(s.toString());
                res.add(new ArrayList(list));
                list.remove(list.size() - 1);
            }
            return;
        }

        // cut
        int subIdx = len - s.length();
        String temp = s.substring(0,idx - subIdx);
        //System.out.print("idx:" + idx + "  temp:" + s.substring(0,idx - subIdx));
        if(judge(temp)){
            list.add(temp);
            //System.out.println("  subtemp:" + s.substring(idx - subIdx));
            dfs(new StringBuilder(s.substring(idx - subIdx)),idx + 1,len);
             list.remove(list.size() - 1);
        }

        // not cut
        dfs(s,idx + 1,len);
    }

    public List<List<String>> partition(String s) {
        dfs(new StringBuilder(s),1,s.length());
        return res;

    }
}

在这里插入图片描述

问题

  • StringBuilder获取子串是substring,没有大写,而且也没有简称,不是subString,不是subStr ,都不是!!是substring

    • substring(strat_idx):从start_idx到末尾
    • substring(start_idx,end_idx):从start_idx到end_idx这段子串 ,不包括end_idx,相当于在end_idx前面一个字符做的分割点
  • String去除空格

    • str.trim()去除前后空格
    • str.replace(" “,”");
    • 正则表达式replaceAll(“\s+”, “”)
  • 我这里回溯的角度可能有问题,导致时间上有很多耗费!

参考实现

暴力搜索 + 迭代优化

暴力搜索

  • 这里举得是区间长度,也就是区间起点,然后列举区间的终点,不同于我们列举每一个分割点!
  • 迭代深度
    • 每一区间的起点的位置
  • 单次迭代的宽度
    *

迭代优化

  • 利用了回文字符串的中间子串也一定是回文字符串的特性,具体如下图!
for(int j = 0;j < n;j ++){
	for(int i = 0;i <= j;i ++){
		if(i == j)	f[i][j] = true;
		else if(s[i] == s[j]){
			if(i + 1 > j -1 || f[i + 1][j - 1])	f[i][j] = true;
		}
	}
}

具体实现代码

class Solution {
    boolean[][] f;
    List<String> list = new ArrayList();
    List<List<String>> res = new ArrayList<>();

    void dfs(String s,int idx){
        int m = s.length();
        if(idx == m){
            res.add(new ArrayList(list));
            return ;
        }

        for(int i = idx ;i < m; i++){
            if(f[idx][i]){
                //System.out.println("idx:" + idx + " i" + i + " substr:"+s.substring(idx,i+1));
                list.add(s.substring(idx,i + 1));
                dfs(s,i+1);
                list.remove(list.size() - 1);
            }
        }
    }

    public List<List<String>> partition(String s) {
        int m = s.length();
        f = new boolean[m][m];
        for(int j = 0;j < m;j ++){
            for(int  i = 0;i <= j;i ++){
                if(i == j)  f[i][j] = true;
                else if(s.charAt(i) == s.charAt(j)){
                    if(i + 1 > j - 1 || f[i + 1][j - 1])    f[i][j] = true;
                }
            }
        }

        dfs(s,0);
        return res;

    }
}

在这里插入图片描述
确实更快,那个回文推导的得稍微记一下!

环形链表II

  • 题目连接
    在这里插入图片描述
    在这里插入图片描述
    注意
  • pos表示-1或者有效索引
  • 不用担心数字越界
  • 空间复杂度要求是O(1)
个人实现
  • 这个明显是用快慢指针,首先判定是否有环,然后在有环的情况下,判定出对应环的起始点!
  • 难点在第二步,不过感觉这个环的起始点,之前好像做过。感觉快慢节点在有环的情况下,应该有特殊情况!

这里还是不知道怎么推导出来的,这题挂了!

如果不强制要求空间复杂度的话,只需要一次遍历就能实现!

这里就不写了,没什么意思!

参考实现
  • 这里推导的比较绕,我看了很多遍,总结起来就是一句话
    • 快慢指针相遇的地方,和链表的头节点分别同时触发一个速度为1的节点遍历,相遇点就是入点

先套一个快慢指针的模板

while(f != null){
	f = f.next;
	s = s.next;
	if(f == null)	return false;
	f = f.next;
	if(f == s)	return true;
}

最终实现代码

/**
 * Definition for singly-linked list.
 * class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) {
 *         val = x;
 *         next = null;
 *     }
 * }
 */
public class Solution {
    public ListNode detectCycle(ListNode head) {
        if(head == null || head.next == null)   return null;
        ListNode s = head;
        ListNode f = head.next;

        // judge whether contains circle
        while(f != null){
            f = f.next;
            s = s.next;
            if(f == null)   return null;
            f = f.next;
            if(f == s){
                s = head;
                f = f.next;
                while(s != f)   {
                    s = s.next;
                    f = f.next;
                }
                return s;
            }
        }

        return null;

    }
}

两个有序链表

  • 题目链接
    在这里插入图片描述
    在这里插入图片描述
  • 第一次练习连接
个人实现
  • 这个题目第二次做了,而且是个简单题,直接遍历就行了
/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public ListNode mergeTwoLists(ListNode list1, ListNode list2) {
        ListNode head1 = list1;
        ListNode head2 = list2;
        ListNode dummy = new ListNode();
        ListNode temp = dummy;
        while(head1 != null && head2 != null){
            if(head1.val < head2.val){
                temp.next = head1;
                head1 = head1.next;
                temp = temp.next;
            }else{
                temp.next = head2;
                head2 = head2.next;
                temp = temp.next;
            }
        }

        temp.next = (head1 == null ? head2:head1);
        return dummy.next;
    }
}

在这里插入图片描述

题目很简单,但是让我想到了某一次字节的面试,面试官觉得我代码写的太差了,那道题是一个大数加法,使用链表表示的,我最后写的太差了!毕竟我已经换了三道题,感觉完蛋了!

总结

  • 今天状态不得行,刷到了第三题,我就厌烦的不行,不过还是得调整一下!
  • 真的是,每天刷题,刷的恶心,恶心的不行!后续还是得加油!
  • 又搞到好晚,我要睡了!
  • 明天面试百度,加油!

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

学习React(状态管理)

随着你的应用不断变大&#xff0c;更有意识的去关注应用状态如何组织&#xff0c;以及数据如何在组件之间流动会对你很有帮助。冗余或重复的状态往往是缺陷的根源。在本节中&#xff0c;你将学习如何组织好状态&#xff0c;如何保持状态更新逻辑的可维护性&#xff0c;以及如何…

【SpingCloud】客户端与服务端负载均衡机制,微服务负载均衡NacosLoadBalancer, 拓展:OSI七层网络模型

客户端与服务端负载均衡机制 可能有第一次听说集群和负载均衡&#xff0c;所以呢&#xff0c;我们先来做一个介绍&#xff0c;然后再聊服务端与客户端的负载均衡区别。 集群与负载均衡 负载均衡是基于集群的&#xff0c;如果没有集群&#xff0c;则没有负载均衡这一个说法。 …

CSS:顶部导航栏固定位置、分类标题栏、底部提示文案固定位置

一、效果图 页面body的css代码 body {position: absolute;width: 100%;height: 100vh;padding: 0;margin: 0;top: 0;left: 0;bottom: 0;background-color #eee;/* overflow: auto;overflow-y: scroll; *//* ::-webkit-scrollbar {display: none;} */ }.content-root {width: 1…

python多进程加速函数运行

python多进程运行可以使函数运行在程序主进程以外&#xff0c;减少主进程的调用&#xff0c;并且可以加速子进程的运行速度   为了测试多进程的加速效果&#xff0c;我们可以通过创建一个包含计算密集型任务的函数&#xff0c;并使用多进程来并行执行这些任务。我们将对比单进…

Telegram曝零日漏洞,可伪装成视频攻击安卓用户

ESET Research在一个地下论坛上发现了一个针对Android Telegram的零日漏洞广告。 ESET将该漏洞命名为“EvilVideo”&#xff0c;并将其报告给Telegram&#xff0c;Telegram于7月11日更新了该应用程序。 EvilVideo允许攻击者发送恶意的有效载荷&#xff0c;这些载荷以视频文件…

《白话机器学习的数学》第2章——学习回归

2.1设置问题 1.机器学习所做的事情正是从数据中进行学习&#xff0c;然后给出预测值。 2.2定义模型 1.一次函数的表达式&#xff1a; 其中θ叫做参数。 在统计学领域&#xff0c;人们常常使用 θ 来表示未知数和推测值。采用 θ加数字下标的形式&#xff0c;是为了防止当未知数…

熟悉set/map了解KV模型和pair结构

set基本介绍 set是key模型,本质是确定一个 元素在不在此容器中,也就是说 set中存储的是一个单一数据 1. set是按照一定次序存储元素的容器 2. 在set中&#xff0c;元素的value也标识它(value就是key&#xff0c;类型为T)&#xff0c; 并且每个value必须是唯一的。set中的元素不…

PHP教程001:PHP介绍和环境配置

文章目录 1、php是什么2、php能做什么3、php程序执行流程4、需要什么基础5、环境介绍5.1、WEB环境5.2、环境集成包3、phpStudio软件下载 1、php是什么 通用&#xff1a;跨平台&#xff0c;如windows、Linux、MacOS开源免费服务器端脚本语言 2、php能做什么 可以快速动态的生…

群管机器人官网源码

一款非常好看的群管机器人html官网源码 搭建教程&#xff1a; 域名解析绑定 源码文件上传解压 访问域名即可 演示图片&#xff1a; 群管机器人官网源码下载&#xff1a;客户端下载 - 红客网络编程与渗透技术 原文链接&#xff1a; 群管机器人官网源码

很酷的仿真翻页书HTML源码,书本页面是加载的图片,基于JQuery实现的翻页特效,结合一些js插件,看起来很酷,在实现在线翻书项目。

仿真翻页书HTML源码https://www.bootstrapmb.com/item/14742 创建一个仿真的翻页书效果在HTML和CSS中可以通过多种方式实现&#xff0c;但通常这也会涉及到JavaScript&#xff08;或jQuery&#xff09;来处理交互和动画。以下是一个简单的示例&#xff0c;展示如何使用HTML、…

openssl 加密

使用tar命令在Linux中加密文件可以通过两种方式实现&#xff1a;使用gzip压缩的同时加密&#xff0c;或者使用加密选项。 1. 使用gzip压缩的同时加密&#xff1a; “ tar cz file1 file2 | openssl enc -e -aes256 -out archive.tar.gz.enc “ – cz&#xff1a;创建tar压缩文…

【数学建模】基于贪心算法的电力市场的输电阻塞管理(附论文及matlab、lingo代码)

适合数学建模新手研究的题目&#xff0c;备战国赛的同学可以拿这道题目练手&#xff0c;本文含论文代码&#xff0c;帮助解题理解思路。 题目&#xff1a; &#xff08;1&#xff09;题目信息&#xff1a; 某电网有若干台发电机组和若干条主要线路&#xff0c;每条线路上的有…

k8s中部署nacos

1 部署nfs # 在k8s的主节点上执行 mkdir -p /appdata/download cd /appdata/download git clone https://github.com/nacos-group/nacos-k8s.git 将nacos部署到middleware的命名空间中 kubectl create namespace middleware cd /appdata/download/nacos-k8s # 创建角色 kub…

鸿蒙界面开发

界面开发 //构建 → 界面 build() {//行Row(){//列Column(){//文本 函数名(参数) 对象.方法名&#xff08;参数&#xff09; 枚举名.变量名Text(this.message).fontSize(40)//设置文本大小.fontWeight(FontWeight.Bold)//设置文本粗细.fontColor(#ff2152)//设置文本颜色}.widt…

乐鑫ACK方案低成本设备开发,智能家居无线技术应用,启明云端乐鑫代理商

随着智能家居行业的蓬勃发展&#xff0c;用户对于智能设备的需求日益增长。乐鑫以其创新的Alexa Connect Kit (ACK) 方案&#xff0c;开启了智能家居设备开发的新篇章。 Alexa Connect Kit&#xff08;ACK&#xff09;方案&#xff0c;不仅提供了一个集成Alexa语音服务的高效开…

Redis八股文(一)

目录 1.什么是Redis&#xff1f; 2.Redis和Memcached有什么区别&#xff1f; 3.为什么Redis作为MySQL的缓存&#xff1f; 4.Redis数据类型及其使用场景分别是什么&#xff1f; 5.五种常见数据类型是怎么实现的&#xff1f; 6.Redis是单线程吗&#xff1f; 7.Redis单线程…

iterm2工具的使用|MAC电脑终端实现分屏|iterm2开启滚动操作

iterm2 工具概括 iTerm2 是一款非常强大的终端工具。 iTerm2 最初是为 macOS 开发的,但也有 Windows 、Linux 发行版&#xff08;Ubuntu、centos…&#xff09;可用。 应用场景 Mac操作系统中想实现终端分屏 iterm2 工具特点 多标签和分屏: 可以在同一个窗口中打开多个标签…

【css】实现扫光特效

对于要重点突出的元素&#xff0c;我们经常可以看到它上面打了一个从左到右的斜向扫光&#xff0c;显得元素亮闪闪的&#xff01;类似于下图的亮光动效 关键步骤 伪元素设置position :absolute【也可以不用伪元素&#xff0c;直接创建一个absolute元素盖在上面】设置渐变line…

基于jeecgboot-vue3的Flowable流程仿钉钉流程设计器-抄送服务处理

因为这个项目license问题无法开源&#xff0c;更多技术支持与服务请加入我的知识星球。 1、因为仿钉钉设计器里抄送人是一个服务任务&#xff0c;所以要根据这个服务任务进行处理 2、前端就是一个抄送&#xff0c;选择人 3、这里用了jeecg的选择人组件 <el-form-item prop…

Java开发之Redis

1、非关系型数据库、快、高并发、功能强大 2、为什么快&#xff1f;内存单线程 非阻塞的IO多路复用有效的数据类型/结构 3、应用&#xff1a;支持缓存、支持事务、持久化、发布订阅模型、Lua脚本 4、数据类型&#xff1a; 5 种基础数据类型&#xff1a;String&#xff08;字…