面试算法题

news2024/11/29 20:40:19

文章目录

  • 数组中的第K个最大元素
    • 快排
  • k个一组反转链表
    • 解法一:栈
    • 解法二:模拟
  • 买卖股票最佳时机
    • 买卖股票最佳时机i
    • 买卖股票最佳时机ii
      • 贪心
  • 无重复长度子串
  • 最长递增子序列
  • 只出现一次的数字 III
  • lru缓存
  • 合并K个升序链表

数组中的第K个最大元素

快排

请添加图片描述

class Solution {
public:
    void quickPartition(vector<int>& nums, int start, int end, int target) {
        // 随机取一个数作为基准

        int random = (end - start) + start;
        
        int base = nums[random];
        // 将该数放到待快排区间开头第一个元素
        swap(nums[start], nums[random]);
        int index = start;
        // 从待快排区间的第二个元素开始,依次与base比较,如果大于等于base则将该元素
        // 交换到index + 1位置,index++,使得最终index前面的元素都比base大。
        for (int i = start + 1; i <= end; ++i) {
            if (nums[i] >= base) {
                swap(nums[index + 1], nums[i]);
                index++;
            }
        }
        // base存放在区间开头,现在需要把它交换到index位置,这就是它在整个有序数组中的位置。
        swap(nums[index], nums[start]);
        // 如果index小于target,需要在右边区间继续快排查找,否则到在边区间查找,
        // 如果等于已经找到目标值不需要递归,这里这么做优化了传统快排的复杂度。
        if (index < target) {
            quickPartition(nums, index + 1, end, target);
        }
        else if (index > target) {
            quickPartition(nums, start, index - 1, target);
        }
    }

    int findKthLargest(vector<int>& nums, int k) {
        // 方法1. 快速排序的分区思想,快排的思想是一次找出一个数的正确位置,
        // 并使得该数左边的元素都比它小,该数右边的元素都比它大,要找出第k
	// 大的元素,只需要在快排的时候采用降序排序,找到下标为k-1的元素即可。

        quickPartition(nums, 0, nums.size() - 1, k - 1);
        return nums[k - 1];
    }
};

k个一组反转链表

解法一:栈

class Solution {
public:
    ListNode* reverseKGroup(ListNode* head, int k) {
        if (k <= 1)//首先判断k的合法性
		return head;

	stack<ListNode *> myStack;//辅助栈,用于转换k个节点的转换
	int count = 0;//进栈的节点数
	ListNode *ptr = head;
	//进栈k个节点
	while (count < k && ptr != NULL){
		myStack.push(ptr);
		ptr = ptr->next;
		++count;
	}
	if (count < k){//如果不足k个,则无需转换
		return head;
	}
	//出栈并且顺序串接好
	//pHead是逆置结果的表头,pEnd是逆置结果的临时表尾
	ListNode *pHead = myStack.top(), *pEnd;
	myStack.pop();
	pEnd = pHead;
	while (count > 1){
		pEnd->next = myStack.top();
		pEnd = pEnd->next;
		myStack.pop();
		--count;
	}
	//递归调用,将ptr后面的链表进行逆置
	pEnd->next = reverseKGroup(ptr, k);
	return pHead;
    }
};

解法二:模拟

思路:可以把整段链表分为

  1. 已反转
  2. 即将反转但未反转
  3. 未反转
class Solution {
public:
    ListNode* reverseKGroup(ListNode* head, int k) {
        if (!head) {
            return head;
        }
        int loop = 0;	//计数第几个节点,用于判断是否
        ListNode* p = head;		
        ListNode* pHead = p;
        ListNode* pLast = p;
        while (p) {
            ++loop;
            if (loop % k == 0) {
                ListNode* temp = reverse(pHead, p);
                if (loop == k) {
                    head = temp;	//第一次到达k时,此时返回的head就是最终的head
                } else {
                    pLast->next = temp;		//非第一次到达k时,把刚反转的那一段链表的头节点接到上一次已反转的尾部
                }
                p = pHead;
                pHead = p->next;
                pLast = p;
            }
            p = p->next;
        }

        return head;
    }

    ListNode* reverse(ListNode* head, ListNode* last) {		//给定一个头节点一个尾节点,反转链表
        ListNode* realhead = last->next;	//把未到达的那个节点连接到尾部,便于后面正常遍历
        while (realhead != last) {
            ListNode* p = head->next;
            head->next = realhead;
            realhead = head;
            head = p;
        }
  
        return realhead;
    }
};

买卖股票最佳时机

买卖股票最佳时机i

  • dp:维护最大利润,维护最小买入值
class Solution {
public:
    int maxProfit(vector<int>& prices) {
        int maxAns = 0;
        int minPrice = 99999;
        for (int i = 0; i < prices.size(); i++) {
           minPrice = min(minPrice, prices[i]); 
           maxAns = max(maxAns,prices[i] - minPrice);
        }
        return maxAns;
    }
};

买卖股票最佳时机ii

贪心

  • 对于 「今天的股价 - 昨天的股价」,得到的结果有 3 种可能:① 正数,② 000,③负数。贪心算法的决策是: 只加正数 。
class Solution {
public:
    int maxProfit(vector<int>& prices) {
        int maxP = 0;
        for (int i = 1; i < prices.size(); i++) {
            maxP += max(0, prices[i] - prices[i-1]);
        }
        return maxP;
    }
};

无重复长度子串

class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        unordered_map <char, int> map;		//
        int left = 0, size = s.length();
        int ans = 1, right = 1;
        map[s[left]] = 1;
        if (!size) {
            return 0;
        }
        while (right < size) {
            if (map.find(s[right]) != map.end()) { //如果遍历的这个字符在map里,把left位置的字符从map里删除,并right不动,left++
                ans = max(ans, right-left);
                map.erase(s[left]);
                ++left;
            } else {		//当遍历的这个字符不存在map里,就往后走,并把该字符添加到map里
                map[s[right]] = 1;
                ++right;
            }
        }
        ans = max(ans, right-left);
        return ans;
    }
};

最长递增子序列

维护dp数组里的最大值
维护已遍历原数组里最大值,每次与最大值比较,如果大于max,就让dp数组的该索引值为++max。否则还为max

class Solution {
public:
    int lengthOfLIS(vector<int>& nums) {
        vector<int> dp(nums.size(), 1);
        dp[0] = 1;
        int ans = 1;
        for (int i = 1; i < nums.size(); i++) {
            for (int j = 0; j < i; j++) {
                if (nums[i] > nums[j]) {
                    dp[i] = max(dp[i], dp[j]+1);
                    ans = max(ans, dp[i]);
                }
            }
        }
        return ans;
    }
};

只出现一次的数字 III

利用一个hashmap,出现一次的保留在map里,出现第二次就从map里删除

class Solution {
public:
    vector<int> singleNumber(vector<int>& nums) {
        unordered_map <int, int> map;
        vector<int> ans;
        for (int i = 0; i < nums.size(); i++) {
            if (map.find(nums[i]) != map.end()) {
                map.erase(nums[i]);
            } else {
                map[nums[i]] = 1;
            }
        }
        for (auto& it : map) {
            ans.push_back(it.first);
        }
        return ans;
    }
};

lru缓存

struct linkList {		//创建双向链表
    int key, value;
    linkList* next;
    linkList* prev;
};
class LRUCache {
public:
    int size;
    int capacity;
    linkList* head;			//保留住头节点位置,头节点的下一个为最新的
    linkList* last;			//保留尾节点,尾节点的上一个为最旧的
    unordered_map <int, linkList*> map;

    LRUCache(int capacity) {		//初始化
        size = 0;
        this->capacity = capacity;
        head = new linkList;
        last = new linkList;
        head->next = last;
        last->prev = head;
    }
    
    int get(int key) {
        if (map.find(key) == map.end()) {	//未找到
            return -1;
        } else {
            moveToFirstNode(map[key]);		//移到头节点后面
            return map[key]->value;
        }
    }
    
    void put(int key, int value) {			
        if (map.find(key) != map.end()) {		//如果在map里找到了该key,就从value保存的节点修改值就好,然后再移到首部
            map[key]->value = value;
            moveToFirstNode(map[key]);
            return;
        }
        if (size < capacity) {					//缓存够的话,直接放进首部
            map[key] = addNode(key, value);
            ++size;
        } else {
            removeNode();
            map[key] = addNode(key, value);		//缓存不够,需要移除尾节点,再把新添加的节点放到首部
        }
    }
    
    linkList* addNode(int key, int value) {
        linkList* p = new linkList;		//设值
        p->value = value;
        p->key = key;
        
        head->next->prev = p;			//头插法
        p->next = head->next;
        p->prev = head;
        head->next = p;
        return p;
    }

    void removeNode() {				//移除最后一个节点
        linkList* pRemove = last->prev;			
        linkList* temp = last->prev->prev;
        temp->next = last;
        last->prev = temp;
        map.erase(pRemove->key);
        delete pRemove;
    }

    void moveToFirstNode(linkList* p) {			//把节点p从中间断开再放入首部
        linkList* temp = p->prev;			//断开,并把分隔开的上下两个节点连接好
        linkList* pNext = p->next;
        temp->next = pNext;
        pNext->prev = temp;

        head->next->prev = p;			//放到首部
        p->next = head->next;
        p->prev = head;
        head->next = p;
    }
};

合并K个升序链表

我们需要维护当前每个链表没有被合并的元素的最前面一个,k 个链表就最多有 k 个满足这样条件的元素,每次在这些元素里面选取 val 属性最小的元素合并到答案中。在选取最小元素的时候,我们可以用优先队列来优化这个过程。

class Solution {
public:
    struct comp {		//	重载运算符
        bool operator () (ListNode* a, ListNode* b) {
            return a->val > b->val;
        }
    };

    priority_queue<ListNode*, vector<ListNode*>, comp> q;

    ListNode* mergeKLists(vector<ListNode*>& lists) {
        for (auto node: lists) {
            if (node) {
                q.push(node);
            }
        }
        ListNode* head = new ListNode();
        ListNode* tail = head;
        while (!q.empty()) {
            ListNode* node = q.top();
            q.pop();
            tail->next = node; 
            tail = tail->next;
            if (node->next) {
                q.push(node->next);
            }
        }
        return head->next;
    }
};

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

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

相关文章

第一个程序

第一个程序 1. 常用DOS命令 1.1 打开命令提示符窗口 1. winR2. cmd3. 按下回车键 1.2 常用命令 2. Path 环境变量的配置 2.1 为什么要配置 Path环境变量 开发 Java程序&#xff0c; 需要使用 JDK 提供的开发工具&#xff0c; 而这些工具在 JDK 的 安装目录的 bin目录 下。未来…

【测试代码 基于Pytorch】的卷积神经网络(CNN) || 【基于Pytorch】的深度卷积神经网络(DCNN)

声明:仅学习使用~ 目录 一、卷积神经网络 CNN1、【基于Pytorch】的卷积神经网络(CNN)2、【基于Pytorch】的深度卷积神经网络(DCNN)一、卷积神经网络 CNN CNN,这里以 LeNet 为例。LeNet神经网络由深度学习三巨头之一的Yan LeCun提出,他同时也是卷积神经网络 (CNN,Convo…

RHCE之路配置本地DNS服务器的正反向解析

第十天 SOA格式 ---&#xff08;序列号&#xff0c;同步时间&#xff0c;重试时间&#xff0c;过期时间&#xff0c;TTL&#xff09; 正向解析 [roota ~]# mount /dev/sr0 /mnt mount: /mnt: WARNING: device write-protected, mounted read-only. [roota ~]# yum install bin…

Java 8 新特性 ---- Lambda 表达式

Java 8 新特性 ---- Lambda 表达式1. Java7与Java8的区别2. Lambda表达式3. 语法4. Lambda 表达式实例5. 变量作用域1. Java7与Java8的区别 // 使用 java 7 排序private void sortUsingJava7(List<String> names){ Collections.sort(names, new Comparator<String&g…

matplotlib中的pyplot实用详解

matplotlib中的pyplot实用详解示例1&#xff1a;使用axes确定子图的位置相关函数详解1、plt.subplot()2、plt.subplots_adjust() 与 plt.axes()来控制子图的位置示例1&#xff1a;使用axes确定子图的位置 import matplotlib.pyplot as plt import numpy as np# 固定随机种子 np…

Typescript 学习笔记(二)高级类型二

交叉类型 交叉类型&#xff08;&&#xff09;&#xff1a;功能类似于接口继承&#xff08;extends&#xff09;&#xff0c;用于组合多个类型为一个类型&#xff08;常用于对象类型&#xff09; interface Person2 {name: string} interface Contact {phone: number} typ…

有一个是对的,就是坚持去做难的事情。

不要总是想着去找那些让自己赚到的工作&#xff0c;你自己心里清楚&#xff0c;自己有几斤几两&#xff0c;配什么样的公司。不要贪&#xff0c;不然最后原本该得到的都没有得到。你找差点的工作心里也踏实对不对&#xff0c;不会说比较慌&#xff0c;每天都过不安稳。不要幻想…

软件设计师--其他高频考点总结

视频2022软件设计师-提炼高频考点-个人学习过程的总结&#xff0c;仅供参考&#xff01;_哔哩哔哩_bilibili 目录 1&#xff0c;网络攻击 2&#xff0c;网络安全 3,防火墙 4&#xff0c;耦合 --模块之间相对独立性的度量 5&#xff0c;内聚--模块间内部元素彼此紧密的程度…

Python与爬虫有什么关系?

爬虫一般是指网络资源的获取&#xff0c;因为python的脚本特征&#xff0c;Python易于配置&#xff0c;对字符的处理也非常灵活&#xff0c;加上python有丰富的网络抓取模块&#xff0c;所以两者经常联系在一起。 接下来我们可以详情了解python到底有什么作用。 首先Python翻译…

B树和B+树的区别

【篇首语】&#xff1a; 渐渐地&#xff0c;面试时被问起数据结构&#xff0c;MySQL调优&#xff0c;索引的原理等。首先感谢《王道计算机考研》的一些课程&#xff0c;让我学到了很多。 其实在这个问题之前&#xff0c;应该先了解扇区、磁道、磁盘存储数据的方式等相关概念&a…

荧光标记染料:diSulfo-Cy3 azide,2055138-89-9,二磺酸-Cy3-叠氮

【中文名称】二磺酸-Cy3-叠氮 【英文名称】 diSulfo-Cy3 azide 【结 构 式】 【CAS】2055138-89-9 【分子式】C33H41KN6O7S2 【分子量】736.94 【纯度标准】95% 【包装规格】1mg&#xff0c;5mg&#xff0c;10mg 【是否接受定制】可进行定制 【外观颜色】 红色固体&#xff0…

Spring注解@NonNull作用 Spring注解@Nullable作用 Spring NonNull 注解作用 Spring Nullable注解作用

Spring注解NonNull作用 Spring注解Nullable作用 Spring NonNull 注解作用 Spring Nullable注解作用 一、概述 在看Spring源码的时候&#xff0c;经常会发现有 NonNull 或 Nullable 注解的标记&#xff0c;一般是在方法上&#xff0c;或在 参数中&#xff0c;本着好奇的心里&…

【JavaWeb】第三章 JavaScript基础

文章目录1、JavaScript介绍2、JavaScript和HTML代码的结合方式2.1 第一种方式2.2 第二种方式3、JS的变量和数据类型4、JS关系运算符5、JS逻辑运算符6、数组7、JS函数的定义8、JS函数的隐形参数arguments9、JS中的自定义对象1、JavaScript介绍 JavaScript&#xff08;JS&#x…

摸鱼时,我用几百张字符画做了个动画......

摸鱼时&#xff0c;我用几百张字符画做了个动画…&#xff0c;话不多说&#xff0c;先来看成果&#xff1a; 完整效果视频已上传至B站&#xff1a;摸鱼时我用Java IO流证明了爱坤&#xff01; 事情是这样的… … 学校马上就要开展第20届程序设计大赛了&#xff0c;半年没有练…

Java对象深拷贝 终极方案 deep clone an object

Java对象深拷贝 终极方案定义 深拷贝深拷贝常见误区spring / apache commons 等工具类的 BeanUtils.copy 方法 ❌正确做法&#xff1a; 上中下3策 ✔json 序列化 (用jackson&#xff0c;别用其他的gson/fastjson/json-lib 等&#xff0c;不解释)objectMapper 工具类初始化1. 对…

CDC Schemes

CDC Schemes 下面是一些questa使用时常见的cdc schemes的解释 reconvergence reconvergence的原理如下图所示 如上图所示,sig1和sig2经sync cell同步过来后,又在组合逻辑上reconvergence了,最后送到rx domain的flip-flop上; Fan-in of a flip-flop includes at least t…

跨境物流美国专线的注意事项是哪些

目前国内运输需求最大的物流运输是美国专线&#xff0c;深圳、广州、杭州等地有很多美国专线货运公司。虽然每个人的选择都比较灵活&#xff0c;但是专线物流运输也有很多注意事项&#xff0c;否则会影响货物的运输。那么对于跨境物流美国专线的注意事项&#xff0c;你了解多少…

7. Spring Boot2.5 安全机制与 REST API 身份验证实战

文章目录Spring Boot2.5 安全机制与 RESTAPI 身份验证实战一、Java Spring Boot 2.5 安全机制Java Spring Boot 2.0 安全机制安全漏洞安全漏洞建议总结&#xff1a;Java Spring SecurityJava 安全框架 Shiro二、Java Spring Boot 2.5 安全实战Spring Security Demo2. WebSecuri…

【Python】pyinstaller打包百科全书

前言 记录pyinstaller打包中的常用命令和报错。 详细的还是去官网自己看吧&#xff0c;这里只记录打包中常用到的命令。 如果我这里帮助不到你&#xff0c; 官网在这里&#xff1a;https://github.com/pyinstaller/pyinstaller 这两篇文章基本覆盖100%的报错了&#xff0c; 参…

【微服务】分布式下服务调用产生的问题之服务容错

服务容错前言模拟高并发场景压测测试服务雪崩效应常见容错方案隔离超时限流熔断降级常见的容错组件HystrixResilience4JSentinel总结前言 上篇中&#xff0c;我们了解了Ribbon的概念&#xff0c;也实现了基于Ribbon的服务调用&#xff0c;但同样也引发了另一个问题&#xff0c…