【算法】实验室2024第一次考核复盘

news2024/9/20 2:57:19

【算法】实验室2024第一次考核复盘

本篇博客将遵循从易到难的原则,依次解析这几道考核题目。

原题链接:

125. 验证回文串 - 力扣(LeetCode)

image-20240421160727408

使用两个指针ij分别从字符串的两端开始,i从左往右,j从右往左。通过两个while循环,ij会跳过所有非字母和非数字的字符。当i小于j时,比较ij指向的字符(转换为小写后),如果不相等,则直接返回false,表示字符串不是回文。

如果相等,则ij各自向中间移动一位,继续比较下一对字符。

如果所有对应的字符都相等,当i大于等于j时,循环结束,返回true,表示字符串是回文。

class Solution {
    public boolean isPalindrome(String s) {
        int i = 0, j = s.length() - 1;
        while(i < j){
            while(i < j && !Character.isLetterOrDigit(s.charAt(i))) i++;
            while(i < j && !Character.isLetterOrDigit(s.charAt(j))) j--;
            if(Character.toLowerCase(s.charAt(i)) != Character.toLowerCase(s.charAt(j))) return false;
            i++; 
            j--;
        }
        return true;
    }
}

原题链接:

392. 判断子序列 - 力扣(LeetCode)

image-20240421160742198

如果s的长度为0,即s为空字符串,那么它自然地是任何字符串的子序列,因此返回true

使用两个指针ij分别遍历字符串sti从0开始,j也从0开始。

j小于t的长度时,循环继续。在每次循环中,比较s中的当前字符(s.charAt(i))和t中的当前字符(t.charAt(j))。

如果这两个字符相等,i增加1(指向s的下一个字符),并且检查是否已经遍历完s的所有字符。如果是,则返回true,因为st的子序列。

如果j遍历完ti没有遍历完s,则s不是t的子序列,方法返回false

class Solution {
    public boolean isSubsequence(String s, String t) {
        if (s.length() == 0) return true;
        for (int i = 0, j = 0; j < t.length(); j++) {
            if (s.charAt(i) == t.charAt(j)) {
                // 若已经遍历完 s ,则提前返回 true
                if (++i == s.length())
                    return true;
            }
        }
        return false;
    }
}

原题链接:

35. 搜索插入位置 - 力扣(LeetCode)

image-20240421160759849

使用两个指针leftright来表示搜索区间,初始时left为0,right为数组长度。

使用while循环进行二分查找,当left小于right时循环继续。

在每次循环中,计算中间索引mid,然后比较nums[mid]target的值。

如果nums[mid]等于target,则找到了目标值,但代码中缺少了返回mid的语句。

如果nums[mid]小于target,则将left设置为mid + 1,表示搜索区间移动到mid的右侧。

如果nums[mid]大于target,则将right设置为mid,表示搜索区间移动到mid的左侧。

leftright相遇时,循环结束,此时left即为target应该插入的位置。

class Solution {
    public int searchInsert(int[] nums, int target) {
        int left = 0, right = nums.length;
        while(left < right) {
            int mid = (left + right) / 2;
            if(nums[mid] == target) {
            } else if(nums[mid] < target) {
                left = mid + 1;
            } else {
                right = mid;
            }
        }
        return 0;
    }
}

原题链接:

147. 对链表进行插入排序 - 力扣(LeetCode)

image-20240421160817172

创建一个哑节点(dummy node)dummy,其值设置为0,它的作用是简化边界情况的处理,因为哑节点不包含在链表的真实元素中,但是可以作为头节点的前一个节点。

使用pre指针指向哑节点,cur指针从head开始遍历链表。

对于链表中的每个节点(cur),在dummypre之间找到合适的插入位置。这是通过内部的while循环实现的,循环条件是pre.next不为空且pre.next.val小于cur.val

找到插入位置后,将cur节点插入到pre.next之前。

更新pre为哑节点,以便为下一个节点的插入做准备。

更新cur为下一个节点,继续遍历链表。

最后,返回哑节点的下一个节点dummy.next,即为排序后的链表的头节点。

class Solution {
    public ListNode insertionSortList(ListNode head) {
        ListNode dummy = new ListNode(0);
        ListNode pre = dummy;
        ListNode cur = head;
        while (cur != null) {
            ListNode tmp = cur.next;
            while (pre.next != null && pre.next.val < cur.val) pre = pre.next;
            cur.next = pre.next;
            pre.next = cur;
            pre = dummy;
            cur = tmp;
        }
        return dummy.next;
    }
}

原题链接:

125. 验证回文串 - 力扣(LeetCode)

image-20240421160910165

遍历字符串中的每个字符,对于大写字母,将其转换为小写(通过ASCII值减去32实现),对于小写字母和数字,直接保留。

过滤掉非字母数字字符,并在过滤后的字符数组中更新字符位置,通过index指针来记录有效字符的个数。

使用两个指针leftright分别从过滤后的字符数组的两端开始,向中间遍历。

如果两端的字符不相等,则返回false,表示字符串不是回文。

如果所有对应的字符都相等,循环结束后返回true,表示字符串是回文。

class Solution {
    public boolean isPalindrome(String str) {
        char[] s = str.toCharArray();
        int n = s.length;
        int index = 0;
        for (int i = 0; i < n; i++) {
            if (s[i] >= 'A' && s[i] <= 'Z') {
                // 大写
                s[index++] = (char) (s[i] + 32);
            } else if ((s[i] >= 'a' && s[i] <= 'z') ||
                    (s[i] <= '9' && s[i] >= '0')) {
                //  小写和数字
                s[index++] = s[i];
            }
        }
        // System.out.println(new String(s, 0, index));
        int left = 0, right = index - 1;
        while (left < right) {
            if (s[left] != s[right]) return false;
            left++;
            right--;
        }
        return true;
    }
}

原题链接:

61. 旋转链表 - 力扣(LeetCode)

image-20240421160921755

找到插入点,分开两个链表,再首尾相接即可。

class Solution {
    public ListNode rotateRight(ListNode head, int k) {
        if(head == null|| k == 0){
            return head;
        }
        ListNode fast = head;
        ListNode slow = head;
        int n = 0;
        while(fast != null){
            fast = fast.next;
            n++;
        }
        if(k % n == 0){
            return head;
        }
        fast = head;
        for(int i = k % n;i >= 0;i--){
            fast = fast.next;
        }
        while(fast != null){
            fast = fast.next;
            slow = slow.next;
        }
        //qiefen
        ListNode newHead = slow.next;
        slow.next = null;
        ListNode pmov = newHead;
        while(pmov != null && pmov.next != null){
            pmov = pmov.next;
        }
        pmov.next = head;
        return newHead;
    }
}

原题链接:

232. 用栈实现队列 - 力扣(LeetCode)

image-20240421160939198

在【算法】栈作队时队亦栈,进为出处出也进-CSDN博客

这篇博客中,我对本题作了比较详细的阐述,就不再赘述啦~

typedef struct {
    int stackIn[200];
    int stackOut[200];
    int topIn;
    int topOut;
} MyQueue;


MyQueue* myQueueCreate() {
    MyQueue* que = (MyQueue*)malloc(sizeof(MyQueue));
    que->topIn = 0;
    que->topOut = 0;
    return que;
}

void myQueuePush(MyQueue* obj, int x) {
    obj->stackIn[obj->topIn] = x;
    obj->topIn = obj->topIn+1;
}

int myQueuePop(MyQueue* obj) {
    //将in栈中元素压入out栈
    int inTop = obj->topIn;
    int outTop = obj->topOut;
    if (outTop == 0) {
        while (inTop > 0) {
            obj->stackOut[outTop++] = obj->stackIn[--inTop];
        }
    }
    //出栈(出队)
    int top = obj->stackOut[--outTop];
    //将out栈中元素压回in栈
    while (outTop > 0) {
        obj->stackIn[inTop++] = obj->stackOut[--outTop];
    }
    obj->topIn = inTop;
    obj->topOut = outTop;
    return top;
}

int myQueuePeek(MyQueue* obj) {
    //队列首个元素即为in栈中最底下的元素
    return obj->stackIn[0];
}

bool myQueueEmpty(MyQueue* obj) {
    if(obj->topIn == 0){ 
        return true;
    }else{
        return false;
    }
}

void myQueueFree(MyQueue* obj) {
    obj->topIn = 0;
    obj->topOut = 0;
}

原题链接:

309. 买卖股票的最佳时机含冷冻期 - 力扣(LeetCode)

image-20240421160956454

如果数组长度小于等于1,意味着没有交易发生,返回0作为利润。

创建一个二维整数数组dp,其中dp[i][j]表示在第i天时,采用第j种策略能够获得的最大利润。数组的三个状态分别代表:

  • dp[i][0]:第i天不持有股票的最大利润。
  • dp[i][1]:第i天持有股票的最大利润。
  • dp[i][2]:第i天已经卖出股票后的最大利润(即在第i天或之前卖出)。

初始化dp[0]数组,其中dp[0][0]为0(不持有股票),dp[0][1]-prices[0](购买股票),dp[0][2]为0(已经卖出股票)。

遍历price数组,从第1天到第n-1天,更新dp数组。对于每一天i:

  • dp[i][0]更新为不持有股票的最大利润,即持有或不持有股票的最大利润(dp[i-1][0]dp[i-1][2])。
  • dp[i][1]更新为持有股票的最大利润,即前一天不持有股票的情况下减去当前天股票价格(dp[i-1][0] - prices[i])或前一天持有股票的最大利润(dp[i-1][1])。
  • dp[i][2]更新为卖出股票后的最大利润,即持有股票的情况下加上当前天股票价格(dp[i-1][1] + prices[i])。

最后,返回第n-1天不持有股票或已经卖出股票的最大利润(dp[n-1][0]dp[n-1][2])。

class Solution {
    public int maxProfit(int[] prices) {
        int n=prices.length;
        if(n<=1) return 0;
        int [][] dp=new int[n][3];
        dp[0][0]=0;
        dp[0][1]=-1*prices[0];
        dp[0][2]=0;
        for(int i=1;i<n;i++){//从[1]...[n-1]
          dp[i][0]=Math.max(dp[i-1][0],dp[i-1][2]);
            dp[i][1]=Math.max(dp[i-1][1],dp[i-1][0]-prices[i]);
            dp[i][2]=dp[i-1][1]+prices[i];

        }
        return Math.max(dp[n-1][0],dp[n-1][2]);
    }
}

原题链接:

238. 除自身以外数组的乘积 - 力扣(LeetCode)

image-20240421161007356

如果数组长度为0,则直接返回空数组,因为没有任何元素可以计算乘积。

创建一个与nums同样长度的数组ans,用于存储每个元素的乘积结果。数组的第一个元素初始化为1,因为任何数与1相乘都等于其本身。

使用一个临时变量tmp来存储从数组末尾开始的累积乘积。

首先,通过一个循环计算出ans中每个元素除了其自身以外左侧所有元素的乘积。

然后,通过另一个循环从数组末尾开始,更新ans中每个元素的乘积,使其包含右侧所有元素的乘积。

class Solution {
    public int[] productExceptSelf(int[] nums) {
        int len = nums.length;
        if (len == 0) return new int[0];
        int[] ans = new int[len];
        ans[0] = 1;
        int tmp = 1;
        for (int i = 1; i < len; i++) {
            ans[i] = ans[i - 1] * nums[i - 1];
        }
        for (int i = len - 2; i >= 0; i--) {
            tmp *= nums[i + 1];
            ans[i] *= tmp;
        }
        return ans;
    }
}

原题链接:

73. 矩阵置零 - 力扣(LeetCode)

image-20240421161016954

获取矩阵的行数m和列数n

创建两个辅助数组hashmhashn,分别用于记录哪些行和列需要被置为0。

首先,遍历整个矩阵,如果发现某个元素为0,则在hashmhashn中标记对应的行和列。

然后,遍历hashm,如果某个索引的值为1,则将矩阵中对应行的所有元素置为0。

最后,遍历hashn,如果某个索引的值为1,则将矩阵中对应列的所有元素置为0。

class Solution {
    public void setZeroes(int[][] matrix) {
        int m = matrix.length;
        int n = matrix[0].length;
        int[] hashm = new int[m];
        int[] hashn = new int[n];
        for(int i = 0;i < m;++i){
            for(int j = 0;j < n;++j){
                if(matrix[i][j] == 0){
                    hashm[i] = 1;
                    hashn[j] = 1;
                }
            }
        }
        for(int i = 0;i < m;++i){
            if(hashm[i] == 1){ 
                System.out.println(i);
                for(int z = 0;z < n;++z){
                    matrix[i][z] = 0;
                }
            }
        }
        for(int j = 0;j < n;++j){
            if(hashn[j] == 1){
                System.out.println(j);
                for(int z = 0;z < m;++z){
                    matrix[z][j] = 0;
                }
            }
        }
    }
}

原题链接:

394. 字符串解码 - 力扣(LeetCode)

在这里插入图片描述

使用一个栈st来存储解码过程中的字符和数字。

使用变量cnt来记录当前处理到字符串s的哪个位置。

使用变量ans来存储最终解码后的字符串。

使用循环遍历字符串s,根据当前字符tmp的类型进行不同的处理:

  • 如果tmp是字母或数字,将其压入栈st
  • 如果tmp"[",将其压入栈,并继续读取下一个字符。
  • 如果tmp是"]",开始解码操作:
    • 弹出栈中直到遇到"["的所有字符,并反转这个字符串,得到需要重复的字符串strtmp
    • 继续弹出栈中直到所有数字被弹出,反转这个字符串得到numstr
    • numstr转换为整数num,表示需要重复的次数。
    • strtmp按照num次重复,并将重复后的字符压回栈中。
  • 如果tmp不在上述情况中,循环继续。
class Solution {
    public String decodeString(String s) {
        Stack<Character> st = new Stack<>();
        String ans = "";
        int cnt = 0;
        while(cnt != s.length()){
            char tmp = s.charAt(cnt);

            //如果是数字
            if(tmp <= '9' || tmp >= 'a'){
                st.push(tmp);
                cnt++;
            }else if(tmp == '['){
                st.push(tmp);
                cnt++;
            }else if(tmp == ']'){
                cnt++;
                String strtmp = "";
                while(st.peek() != '['){
                    strtmp += st.pop();
                }
                st.pop();
                String numstr = "";
                while(!st.isEmpty() && st.peek() <= '9'){
                    numstr += st.pop();
                }
                String numstrtrue = "";
                int n = numstr.length()-1;
                while(n >= 0){
                    numstrtrue += numstr.charAt(n);
                    n--;
                }
                int num = Integer.parseInt(numstrtrue);
                for(int i = 0;i < num;++i){
                    for(int j = strtmp.length()-1;j >= 0;--j){
                        st.push(strtmp.charAt(j));
                    }
                }
                
            }else{
                continue;
            }
        }
        for(char ch : st){
            ans += ch;
        }
        return ans;
    }
}

原题链接:

23. 合并 K 个升序链表 - 力扣(LeetCode)

image-20240421161055616

合并两个有序链表升级版~

class Solution {
    public ListNode mergeKLists(ListNode[] lists) {
        if(lists.length == 0) return null;
        if(lists.length == 1) return lists[0];
        for(int i = 1;i < lists.length;++i){
            lists[0] = MergeLists(lists[0],lists[i]);
        }
        return lists[0];
    }
    public ListNode MergeLists(ListNode l1,ListNode l2){
        ListNode dummy = new ListNode(0);
        ListNode pmov = dummy;
        while(l1 != null && l2 != null){
            if(l1.val < l2.val){
                pmov.next = l1;
                l1 = l1.next;
            }else{
                pmov.next = l2;
                l2 = l2.next;
            }
            
            pmov = pmov.next;
        }
        if(l1 == null){
            pmov.next = l2;
        }else{
            pmov.next = l1;
        }
        return dummy.next;
    }
}

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

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

相关文章

MySQL如何避免全表扫描?

MySQL如何避免全表扫描&#xff1f; 这篇文章解释了何时以及为什么MySQL会执行全表扫描来解析查询&#xff0c;以及如何避免在大型表上进行不必要的全表扫描。 何时会发生全表扫描 MySQL使用全表扫描&#xff08;在EXPLAIN输出中的type列显示为ALL&#xff09;来解析查询的几…

继东风一汽通信后,天磊咨询再次与东风集团达成深度业务合作

&#xff08;天磊咨询总经理&#xff1a;刘文喜&#xff09; 在风起云涌的市场激战中&#xff0c;天磊咨询凭借其出类拔萃的专业实力与服务品质&#xff0c;犹如一颗璀璨明星般脱颖而出&#xff0c;成功与赫赫有名的东风集团达成业务合作。这一合作的达成&#xff0c;不单彰显…

用java实现PDF的下载

1.下载PDF模版 2.导入依赖 <dependency><groupId>com.itextpdf</groupId><artifactId>itext7-core</artifactId><version>7.2.5</version><type>pom</type></dependency> 3.完整代码 package com.by.controller…

数据存储的大小端和测试程序

1.引言 计算机和嵌入式产品中数据的存储方式分为大端和小端两种方式。为什么呢&#xff1f;因为对于大多数设备都需要存储超过1个字节的数据单元。比如&#xff0c;你要表达0x12345678这个数字。使用1个字节的存储空间是肯定完成不了的。因此&#xff0c;你必须使用4个字节的空…

Postgres数据库中的死锁是如何产生的,如何避免和解决?

文章目录 死锁的产生原因如何避免死锁如何解决死锁示例代码查询死锁信息终止事务 在Postgres数据库中&#xff0c;死锁是一种特殊的情况&#xff0c;其中两个或多个事务相互等待对方释放资源&#xff0c;从而导致它们都无法继续执行。这种情况通常发生在多个事务尝试以不同的顺…

HarmonyOS NEXT 使用Canvas实现模拟时钟案例

介绍 本示例介绍利用 Canvas 和定时器实现模拟时钟场景&#xff0c;该案例多用于用户需要显示自定义模拟时钟的场景。 效果图预览 使用说明 无需任何操作&#xff0c;进入本案例页面后&#xff0c;所见即模拟时钟的展示。 使用说明 无需任何操作&#xff0c;进入本案例页…

2024化工制造企业数字化白皮书

来源&#xff1a;蓝凌研究院 中国石油和化学工业联合会发布2023年中国石油和化工行业经济运行情况。数据显示&#xff0c;2023年&#xff0c;我国石化行业实现营业收入15.95万亿元&#xff0c; 同比下降1.1%&#xff0c;利润总额8733.6亿元&#xff0c;行业经济运行总体呈现低…

FastJson2中FastJsonHttpMessageConverter找不到类问题

问题描述 如果你最近也在升级FastJson到FastJson2版本&#xff0c;而跟我一样也遇到了FastJsonHttpMessageConverter找不到类问题以及FastJsonConfig找不到问题&#xff0c;那么恭喜你&#xff0c;看完本文&#xff0c;安装完fastjson2、fastjson2-extension、fastjson2-exte…

Ubuntu 安装 wine

本文所使用的 Ubuntu 系统版本是 Ubuntu 22.04 ! 如果你使用 Ubuntu 系统&#xff0c;而有些软件只在 Windows 上运行&#xff0c;例如&#xff1a;PotPlayer&#xff0c;那么该如何在 Ubuntu 系统中使用到这些 Windows 的软件呢&#xff1f;答案是安装 wine。 简单的安装步骤如…

ZeRO论文阅读

一.前情提要 1.本文理论为主&#xff0c;并且仅为个人理解&#xff0c;能力一般&#xff0c;不喜勿喷 2.本文理论知识较为成体系 3.如有需要&#xff0c;以下是原文&#xff0c;更为完备 Zero 论文精读【论文精读】_哔哩哔哩_bilibili 二.正文 1.前言 ①为什么用该技术&…

负载均衡——华为云ELB

登陆华为云--点击控制台 首先购买弹性云服务器ECS &#xff08;能省则省&#xff09; 基础配置 网络配置 高级配置 &#xff08;购买两台&#xff09; 点击购买 在安全组开放了一个端口9090 分别登陆两台后端服务器&#xff0c;打开http服务于9090端口 用 nohup python …

腾讯云服务器,部署mysql数据库后无法远程访问?

一&#xff0c;首先确定自己部署的数据库&#xff0c;是否可以正常登录&#xff0c;验证部署是否是否成功 mysql -u root -p二、放开mysql远程访问权限&#xff0c;依次输入这些命令 create user root% identified with mysql_native_password by xxxxx; grant all privilege…

linux 设备树-of_address_to_resource

实例分析-reg 属性解析(基于ranges属性) /{#address-cells <0x01>;#size-cells <0x01>;soc {compatible "simple-bus";#address-cells <0x01>;#size-cells <0x01>;ranges <0x7e000000 0x3f000000 0x1000000 0x40000000 0x40000000…

lesson03:类和对象(中)

1.类的6个默认的成员函数 2.构造函数 3.析构函数 4.拷贝构造函数 1.类的6个默认的成员函数 空类&#xff08;类中一个成员都没没有&#xff09;会有成员函数吗&#xff1f; 其实是有的&#xff01;如果我们在类中什么都不写&#xff0c;编译器会自动生成6个默认成员函数&a…

HTML的学习-通过创建相册WEB学习HTML-第二部分

文章目录 二、学习开始3.6、form元素示例&#xff1a;添加form元素示例&#xff1a;action属性添加到form属性中 3.7、input元素示例&#xff1a;在input属性中添加参数 3.8、button元素示例&#xff1a;在button中添加type元素示例&#xff1a;定义单选按钮radio 3.9、id属性示…

时序分析基础(6)——input delay时序分析

1 简介 FPGA对于外部的时钟以及数据的延时信息是不知道的&#xff0c;在低速时钟且时钟发射沿在数据正中心的时候&#xff0c;一般可以不做约束来直接使用。但是到了高速时钟或者双沿采样或者发射沿和数据对齐的情况下&#xff0c;这时候就需要告诉VIVADO外部的时钟与数据情况来…

[2021最新]大数据平台CDH存储组件kudu之启用HA高可用(添加多个master)

今天在做kudu高可用的时候没有参考官网&#xff0c;直接按照常规方式&#xff08;添加角色—>编辑属性—>启动&#xff09;结果发现报错&#xff1f;然后参考了一下文档之后发现这玩意儿还有点玄学&#xff0c;做一下记录。 1.添加两个master。kudu master有leader和foll…

革命性创新,实景AI无人自动直播系统,轻松实现24小时日不落直播卖券。

革命性创新&#xff01;实景AI无人自动直播系统&#xff0c;轻松实现24小时日不落直播卖券&#xff01; 最近&#xff0c;越来越多的朋友纷纷关注到了AI自动直播带货的新玩法&#xff0c;并且也都想要开设自己的自动直播间。然而&#xff0c;对于这种自动讲解、自动回复的直播…

docker-003镜像制作

步骤 使用docker commit提交容器使之成为镜像以ubuntu安装vim后的容器为例 1 ubuntu安装vim 启动容器 docker run -it --nameubuntu-vim ubuntu /bin/bash安装vim apt-get update apt-get install vim2 提交容器作为镜像 查看容器 docker ps -a提交容器作为镜像 命令格式&…

js 打印网页时没有背景色,window.print打印背景色丢失

页面效果 打印效果 需要在打印的容器里增加下面代码 /*webkit 为Google Chrome、Safari等浏览器内核*/ -webkit-print-color-adjust: exact; /*解决火狐浏览器打印*/ print-color-adjust: exact; color-adjust: exact; 完整写法 我为了方便直接写*&#xff0c;这样所有元素都…