浙江保融科技2025实习生校招校招笔试分享

笔试算法题一共是有4道,第一道是手搓模拟实现一个ArrayList,第二道是判断字符串是否回文,第三道是用代码实现1到2种设计模式。

目录

一.模拟实现ArrayList

二.判断字符串是否回文

▐ 解法一

▐ 解法二

▐ 解法三

三.代码实现设计模式


一.模拟实现ArrayList

首先,要实现一个ArrayList就必须得知道ArrayList有哪些方法,他相较于别的数据结构有什么特性。

顺序表是一种线性数据结构,是数据元素按照线性顺序存储的数据结构,通常使用数组实现。顺序表中的元素以一定的顺序排列,每个元素都可以通过下标来进行访问。顺序表支持随机访问,可以快速地访问任意一个元素,但插入或删除元素时需要移动其余元素,效率较低。

这是ArrayList的API文档:ArrayList - Java17中文文档

我们可以基于数组实现ArrayList

    public int[] arr;//使用数组来实现ArrayList
    public int usedSize;//
    public static final int DEFAULT_SIZE = 10;

有了基础的数据结构以后,我们就可以通过其中的 usedSize 和 arr 灵活的去操作顺序表。

对于ArrayList我们至少要实现以下的一些功能

public interface Ilist {
    // 新增元素,默认在数组最后新增
    public void add(int data);
    // 在 pos 位置新增元素
    public void add(int pos, int data);
    // 判定是否包含某个元素
    public boolean contains(int toFind);
    // 查找某个元素对应的位置
    public int indexOf(int toFind);
    // 获取 pos 位置的元素
    public int get(int pos);
    // 给 pos 位置的元素设为 value
    public void set(int pos, int value);
    //删除第一次出现的关键字key
    public void remove(int toRemove);
    // 获取顺序表长度
    public int size();
    // 清空顺序表
    public void clear();
}

对应上述的接口,可以按照如下实现 

import java.util.Arrays;

public class MyArrayList implements Ilist {
    public int[] arr;
    public int usedSize;
    public static final int DEFAULT_SIZE = 5;
    
    public MyArrayList() {
        arr = new int[DEFAULT_SIZE];
    }
    
    public void display() {
        for (int x : arr) {
            System.out.print(x + " ");
        }
        System.out.println();
    }
    
    // 新增元素,默认在数组最后新增
    public void add(int data) {
        //判断满了之后要扩容
        if (arr.length == usedSize) {
            arr = Arrays.copyOf(arr, DEFAULT_SIZE * 2);
        }
        arr[usedSize] = data;
        usedSize++;
    }
    
    // 在 pos 位置新增元素
    public void add(int pos, int data) {
        cheakPos(pos);
        //判断满了之后要扩容
        if (arr.length == usedSize) {
            arr = Arrays.copyOf(arr, DEFAULT_SIZE * 2);
        }
        //移动元素留出空位
        for (int i = usedSize - 1; i >= pos; i--) {
            arr[i + 1] = arr[i];
        }
        arr[pos] = arr[pos - 1];
        //给pos位置元素赋值
        arr[pos - 1] = data;
        usedSize++;
    }
    
    // 判定是否包含某个元素
    public boolean contains(int toFind) {
        for (int i = 0; i < usedSize; i++) {
            if (arr[i] == toFind)
                return true;
        }
        return false;
    }
    
    // 查找某个元素对应的位置
    public int indexOf(int toFind) {
        for (int i = 0; i < usedSize; i++) {
            if (arr[i] == toFind)
                return i + 1;
        }
        return -1;
    }
    
    // 获取 pos 位置的元素
    public int get(int pos) {
        //检查输入位置是否合法
        cheakPos(pos);
        //检查顺序表是否为空
        cheakEmpty();
        return arr[pos];
    }
    
    // 给 pos 位置的元素设为 value
    public void set(int pos, int value) {
        //检查输入位置是否合法
        cheakPos(pos);
        //检查顺序表是否为空
        cheakEmpty();
        arr[pos-1] = value;
    }
    
    //删除第一次出现的关键字key
    public void remove(int toRemove) {
        //检查顺序表是否为空
        cheakEmpty();
        int delPos = indexOf(toRemove);
        for (int i = delPos; i < usedSize; i++) {
            arr[i-1] = arr[i];
        }
        arr[usedSize-1] = arr[usedSize];
        usedSize--;
    }
    
    // 获取顺序表长度
    public int size() {
        //检查顺序表是否为空
        cheakEmpty();
        return usedSize;
    }
    
    // 清空顺序表
    public void clear() {
        usedSize = 0;
    }
    
    private void cheakPos(int pos) {
        if (pos < 0 || pos > usedSize)
            throw new ExceptionOfPos("pos位置不能为:" + pos);
    }
    
    private void cheakEmpty() {
        if (usedSize == 0)
            throw new ExceptionOfEmpty("当前顺序表为空,无法操作");
    }
}

最后俩个自定义异常用来处理 pos 位置非法和顺序表为空。 


二.判断字符串是否回文

这道题目在leetcode上也是有资源的,这里将链接给出:LCR 018. 验证回文串 - 力扣(LeetCode)

给定一个字符串 s ,验证 s 是否是 回文串 ,只考虑字母和数字字符,可以忽略字母的大小写。本题中,将空字符串定义为有效的 回文串 

示例 1:

输入: s = "A man, a plan, a canal: Panama"
输出: true
解释:"amanaplanacanalpanama" 是回文串

示例 2:

输入: s = "race a car"
输出: false
解释:"raceacar" 不是回文串

▐ 解法一

可以采用双指针法,设置俩个指针分别指向字符串的首个和末尾元素,然后利用他们挨个遍历比较。

首先将原有的字符串去除大写,通过 toLowerCase 将原字符串全部转化为小写,并且通过 replaceAll 利用正则表达式将所有的非字母非数字的元素全部删除掉,然后就得到了一个不包含其他字符的字符串。

在得到这么一个字符串后,为了方便我们遍历其中的每个元素,我们可以将这个字符串转化为字符数组,然后定义一个左右双指针来遍历整个数组,如果在其中某一个步骤首尾元素不相同,我们就直接返回 false 。正常情况则继续遍历下一轮,最后得出结论。

class Solution {
    public boolean isPalindrome(String s) {
        s= s.toLowerCase().replaceAll("[^a-z0-9]", "");
        char[] charArray = s.toCharArray();
        int first = 0;
        int last = charArray.length - 1;
        while (first <= last) {
            if (charArray[first] != charArray[last]) {
                return false;
            }
            first++;
            last--;
        }
        return true;
    }
}

▐ 解法二

我们可以采取直接对比原字符串和该字符串的镜像字符串,如果他们相同,则说明他们是回文串。

要实现这样的对比,首先第一步要做的还是对字符串的过滤,需要将其中的特殊字符和大小写过滤掉,为了方便操作,我们使用 StringBuffer 来进行字符串的拼接操作,我们对字符串的每一个字符都进行判断,只有该字符是字母和数字的时候才将其放入 StringBuffer 进行拼接。

最后对于得到的完整字符串,我们再调用 reverse 方法对齐进行镜像的反转,然后将俩个字符串对比得出结论。

class Solution {
    public boolean isPalindrome(String s) {
        // 创建一个StringBuffer对象来存储处理后的字符
        StringBuffer buffer = new StringBuffer();
        // 遍历输入字符串
        for (int i = 0; i < s.length(); i++) {
            char c = s.charAt(i);
            // 仅当字符是字母或数字时才将其加入 buffer
            if (Character.isLetterOrDigit(c)) {
                buffer.append(Character.toLowerCase(c));
            }
        }
        // 创建一个新的StringBuffer对象,它是buffer的反转
        StringBuffer rebuffer = new StringBuffer(buffer).reverse();
        // 检查rebuffer和buffer是否相等
        return buffer.toString().equals(rebuffer.toString());
    }
}

▐ 解法三

同样是使用双指针法,但不同的是我们这一次直接对原字符串进行操作,这样就可以避免浪费额外的空间去存储中间步骤。

对于双指针的基本概念这里就不再赘述,在判断的时候需要对于每一步的字符进行额外的判断,每一个步骤都要保证左指针小于右指针,并且俩个指针指向的元素必须是字母和数字。

在对俩个字符比较的时候需要调用 toLowerCase 屏蔽大小写差异。

class Solution {
    public boolean isPalindrome(String s) {
        int left = 0;
        int right = s.length() - 1;
        while (left < right) {
            //保证左指针的指向始终为需要判断的字母和数字
            while (left < right && !Character.isLetterOrDigit(s.charAt(left))) {
                left++;
            }
            //保证右指针的指向始终为需要判断的字母和数字
            while (left < right && !Character.isLetterOrDigit(s.charAt(right))) {
                right--;
            }
            if (left < right) {
                //如果左指针和右指针指向的字母不同,则直接返回false
                if (Character.toLowerCase(s.charAt(left)) != Character.toLowerCase(s.charAt(right))) {
                    return false;
                }//左右指针指向的元素相同,则进行下一次判断
                left++;
                right--;
            }
        }
        return true;
    }
}

三.代码实现设计模式

单例模式:确保一个类只有一个实例,并提供一个全局访问点。

public class Singleton {
    private static Singleton instance;
    
    private Singleton() {}

    public static synchronized Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton();
        }
        return instance;
    }
}

工厂模式:定义一个创建对象的接口,但让子类决定实例化哪一个类。工厂方法让类的实例化推迟到子类。

public interface Product {
    void use();
}

public class ConcreteProductA implements Product {
    public void use() {
        System.out.println("Using Product A");
    }
}

public class ConcreteProductB implements Product {
    public void use() {
        System.out.println("Using Product B");
    }
}

public abstract class Factory {
    public abstract Product createProduct();
}

public class ConcreteFactoryA extends Factory {
    public Product createProduct() {
        return new ConcreteProductA();
    }
}

public class ConcreteFactoryB extends Factory {
    public Product createProduct() {
        return new ConcreteProductB();
    }
}

观察者模式:定义对象间的一对多依赖,当一个对象改变状态时,所有依赖的对象都会收到通知并自动更新。

import java.util.ArrayList;
import java.util.List;

public interface Observer {
    void update(String message);
}

public class ConcreteObserver implements Observer {
    private String name;

    public ConcreteObserver(String name) {
        this.name = name;
    }

    public void update(String message) {
        System.out.println(name + " received: " + message);
    }
}

public interface Subject {
    void attach(Observer observer);
    void detach(Observer observer);
    void notifyObservers();
}

public class ConcreteSubject implements Subject {
    private List<Observer> observers = new ArrayList<>();
    private String message;

    public void attach(Observer observer) {
        observers.add(observer);
    }

    public void detach(Observer observer) {
        observers.remove(observer);
    }

    public void notifyObservers() {
        for (Observer observer : observers) {
            observer.update(message);
        }
    }

    public void setMessage(String message) {
        this.message = message;
        notifyObservers();
    }
}



 本次的分享就到此为止了,希望我的分享能给您带来帮助,创作不易也欢迎大家三连支持,你们的点赞就是博主更新最大的动力!如有不同意见,欢迎评论区积极讨论交流,让我们一起学习进步!有相关问题也可以私信博主,评论区和私信都会认真查看的,我们下次再见

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

189.二叉树:把二叉搜索树转换为累加树(力扣)

代码解决 /*** Definition for a binary tree node.* struct TreeNode {* int val;* TreeNode *left;* TreeNode *right;* TreeNode() : val(0), left(nullptr), right(nullptr) {}* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}* Tre…

深度神经网络——决策树的实现与剪枝

概述 决策树 是一种有用的机器学习算法&#xff0c;用于回归和分类任务。 “决策树”这个名字来源于这样一个事实&#xff1a;算法不断地将数据集划分为越来越小的部分&#xff0c;直到数据被划分为单个实例&#xff0c;然后对实例进行分类。如果您要可视化算法的结果&#xf…

【linux】操作系统使用wget下载网络文件,内核tcpv4部分运行日志

打印日志代码及运行日志(多余日志被删除了些)&#xff1a; 登录 - Gitee.comhttps://gitee.com/r77683962/linux-6.9.0/commit/55a53caa06c1472398fac30113c9731cb9e3b482 测试步骤和手段&#xff1a; 1、清空 kern.log&#xff1b; 2、使用wget 下载linux-6.9.tar.gz&…

webgis 之 地图投影

地图投影 什么是地图投影目的种类等角投影的分类墨卡托投影Web 墨卡托投影 参考小结 为了更好地展示地球上的数据&#xff0c;需要将地球投影到一个平面上。地图投影是一个数学问题&#xff0c;按照一定的几何关系&#xff0c;将地球上的经纬度坐标映射到一个平面上的坐标。地球…

c++里 父类私有的虚函数,也是可以被子类重写和继承的。但父类私有的普通函数,子类无法直接使用

谢谢 。今天看课本上有这么个用法&#xff0c;特测试一下。这样就也可以放心的把父类的私有函数列为虚函数了&#xff0c;或者说把父类的虚函数作为私有函数了。 再补充一例&#xff1a;

用Nuitka打包 Python,效果竟如此惊人!

目录 为什么选择Nuitka&#xff1f; Nuitka的工作原理 Nuitka的工作流程大致如下&#xff1a; 安装Nuitka 实战案例 示例代码 打包程序 运行可执行文件 进阶技巧 优化选项 多文件项目 打包第三方库 使用Python开发一个程序后&#xff0c;将Python脚本打包成独立可执…

小红书xs-xt解密

在进行小红书爬虫的时候,有一个关键就是解决动态密文的由来 这边用atob对X-S密文进行解密 可以看到他是一个字符串 可以发现他本来是一个json对象,因为加密需要字符串,所以将json对象转化 为了字符串 而在js中,常用JSON.stringify进行json对象到字符串的转化。 这边将JS…

无版权图片素材搜索网站,解决无版权图片查找问题

在数字内容创作领域&#xff0c;图片素材的选择至关重要。一张高质量、合适的图片不仅能够吸引读者的眼球&#xff0c;还能有效传达信息。然而&#xff0c;找到既免费又无版权限制的图片素材并非易事。小编将为大家介绍几个解决这一问题的无版权图片素材搜索网站&#xff0c;这…

第19章 大数据架构设计理论与实践

19.1 传统数据处理系统存在的问题 海量数据的&#xff0c;数据库过载&#xff0c;增加消息队列、甚至数据分区、读写分离、以及备份以及传统架构的性能的压榨式提升&#xff0c;都没有太明显的效果&#xff0c;帮助处理海量数据的新技术和新架构开发被提上日程。 19.2 大数据处…

国产MCU芯片(2):东软MCU概览及触控MCU

前言: 国产芯片替代的一个主战场之一就是mcu,可以说很多国内芯片设计公司都打算或者已经在设计甚至有了一款或多款的量产产品了,这也是国际大背景决定的。过去的家电市场、过去的汽车电子市场,的确国产芯片的身影不是很常见,如今不同了,很多fabless投身这个行业,一种是…

性能测试并发量评估新思考:微服务压力测试并发估算

性能测试并发量评估新思考 相信很多人在第一次做压力测试的时候&#xff0c;对并发用户数的选择一直有很多的疑惑&#xff0c;那么行业内有一些比较通用的并发量的计算方法&#xff0c;但是这些方法在如今微服务的架构下多少会有一些不适合&#xff0c;下面的文章我们对这些问题…

从0开始C++(三):构造函数与析构函数详解

目录 构造函数 构造函数的基本使用 构造函数也支持函数重载 构造函数也支持函数参数默认值 构造初始化列表 拷贝构造函数 浅拷贝和深拷贝 析构函数 总结 练习一下ヽ(&#xffe3;▽&#xffe3;)&#xff89; 构造函数 构造函数的基本使用 构造函数是一种特殊的成…

不知道怎么下载原版系统,这几个原版系统下载网站可以帮你

电脑是我们日常办公生活中必备不可少的设备&#xff0c;无论是个人使用还是企业部署&#xff0c;拥有一个稳定、安全且纯净的操作系统对于保障数据安全和提升使用体验至关重要。然而&#xff0c;网络上充斥着各种二次打包的系统版本&#xff0c;这些版本往往携带了第三方软件或…

班古精准营养X朗格力:教你如何应对慢阻肺

#肺科营养#朗格力#班古营养#复合营养素#肺部营养#肺部健康# 肺是除皮肤外人体中唯一直接与外界联系的器官。一副好肺,能为身体供应充足的氧气,使生命动力更足,人体免疫力、自愈力更强。肺好,生命动力就足,保肺就是保命!但有不少人却没能拥有健康的肺,而是患上了慢阻肺。 专家指…

国外创意二维码活动:喜力Heineken助力爱尔兰濒临倒闭酒吧转型博物馆?

今天分享一个很有意思的国外二维码活动案例。爱尔兰酒馆拥有非常悠久的历史&#xff0c;闻名于世界。但是因为经营成本、税收等的不断增加&#xff0c;自2005年起&#xff0c;四分之一的爱尔兰酒吧相继关闭&#xff0c;这其中包括拥有1229年历史的世界上最古老的酒吧。 于是&a…

Hi3861 OpenHarmony嵌入式应用入门--点灯

本篇实现对gpio的控制&#xff0c;通过控制输出进行gpio的点灯操作。 硬件 我们来操作IO2&#xff0c;控制绿色的灯。 软件 GPIO API API名称 说明 hi_u32 hi_gpio_deinit(hi_void); GPIO模块初始化 hi_u32 hi_io_set_pull(hi_io_name id, hi_io_pull val); 设置某个IO…

用群辉NAS打造影视墙(Video Station篇)

目录 一、群辉套件Video Station 1、安装 2、进入系统 3、配置刮削器 4、获取TMDB网站API密钥 5、配置DNS (1)开启SSH (2)使用终端工具连接到NAS (3)修改hosts文件 (4)再次测试连接 6、设置目录 二、手机端APP设置 三、电视端APP 四、解决影视信息错误 N…

TikTok API接口——获取TikTok用户QRcode二维码

一、引言 在数字化时代&#xff0c;QRcode二维码已经成为连接线上线下的重要桥梁。在社交媒体领域&#xff0c;TikTok作为短视频领域的佼佼者&#xff0c;用户量庞大且活跃度高。为了满足用户之间更便捷的互动需求&#xff0c;我们特别开发了一款针对TikTok平台的接口&#xf…

MATLAB神经网络---lstmLayer(LSTM 长短期记忆神经网络)

前言 描述LSTM就要先描述一下循环神经网络 循环神经网络 循环神经网络通过使用带自反馈的神经元&#xff0c;使得网络的输出不仅和当前的输入有关&#xff0c;还和上一时刻的输出相关&#xff0c;于是在处理任意长度的时序数据时&#xff0c;就具有短期记忆能力。 如下是一个…

内存优化技巧:让数据处理更高效

Pandas无疑是我们数据分析时一个不可或缺的工具&#xff0c;它以其强大的数据处理能力、灵活的数据结构以及易于上手的API赢得了广大数据分析师和机器学习工程师的喜爱。 然而&#xff0c;随着数据量的不断增长&#xff0c;如何高效、合理地管理内存&#xff0c;确保Pandas Da…