面试经典150题【121-130】

文章目录

  • 面试经典150题【121-130】
    • 215.数组中的第k大元素
    • 502.IPO
    • 373.查找和最小的K对数字
    • 295.数据流的中位数
    • 108.将有序数组转换为二叉搜索树
    • 148.排序链表
    • 427.建立四叉树
    • 23.合并K个升序链表
    • 53.最大子数组和
    • 918.环形子数组的最大和

面试经典150题【121-130】

4道堆,4道分治,2道Kadane算法。

215.数组中的第k大元素

在这里插入图片描述
这个有三种考察思路。一个是调用优先队列的API,一个是手写堆,一个是写快速选择。
法一:调用优先队列的API

class Solution {public int findKthLargest(int[] nums, int k) {PriorityQueue<Integer> heap = new PriorityQueue<>();for (int num : nums) {heap.add(num);if (heap.size() > k) {heap.poll();}}return heap.peek();}
}

法二:手写堆:
简化了一下,对于初始化直接用的快排。不写上浮操作了。

class Solution {public int findKthLargest(int[] nums, int k) {MinHeap heap1=new MinHeap(nums,k);for(int i=k;i<nums.length;i++){heap1.add(nums[i]);}return heap1.heap[0];}class MinHeap{private int[]heap;public int size;MinHeap(int[] nums,int k){heap=new int[k];size = k;System.arraycopy(nums, 0, heap, 0, k);Arrays.sort(heap);}public void add(int num){if(num<=heap[0]) return;heap[0]=num;adjust();}public void adjust(){int i=0;while(true){if(2*i+1>size-1) return;if(2*i+2>size-1){if(heap[i]>heap[2*i+1]){swap(heap,i,2*i+1);}return;}int minIndex=2*i+2;if(heap[2*i+1]<heap[2*i+2]) minIndex=2*i+1;if(heap[i]<=heap[minIndex]) break; //不用再往下走了else{swap(heap,i,minIndex);i=minIndex;}}}private void swap(int[]nums,int a,int b){int temp=nums[a];nums[a]=nums[b];nums[b]=temp;}}
}

法三:快速排序选择,不建议。
原地的一直报错。开新数组还好一点。

class Solution {public int findKthLargest(int[] nums, int k) {List<Integer> numList = new ArrayList<>();for (int num : nums) {numList.add(num);}return quickSelect(numList, k);}private int quickSelect(List<Integer> nums, int k) {Random rand=new Random();int pivot = nums.get(rand.nextInt(nums.size()));List<Integer> big = new ArrayList<>();List<Integer> equal = new ArrayList<>();List<Integer> small = new ArrayList<>();for (int num : nums) {if (num > pivot)big.add(num);else if (num < pivot)small.add(num);elseequal.add(num);}if(big.size()>=k) return quickSelect(big,k);if(nums.size()-small.size()<k){return quickSelect(small,k- big.size()-equal.size());}//不在big里也不在small里return pivot;}
}

502.IPO

在这里插入图片描述

public class LC502 {public static void main(String[] args) {int k=2,w=0;int[] profits={1,2,3};int[] capital={0,1,1};System.out.println(findMaximizedCapital(k,w,profits,capital));}public static int findMaximizedCapital(int k, int w, int[] profits, int[] capital) {int n=profits.length;List<int[]> list=new ArrayList<>();for(int i=0;i<n;i++){list.add(new int[]{capital[i],profits[i]});}//按照容量排序,从小到大Collections.sort(list,(a,b)-> a[0]-b[0]);//设置一个大根堆,每次只拿利润最大的一个PriorityQueue<Integer> q=new PriorityQueue<>((a,b)->b-a);int i=0;while(k-->0){//如果这个任务可以执行了,就把他放到大根堆里while(i<n && list.get(i)[0]<=w){q.add(list.get(i)[1]);i++;}//如果一个任务也执行不了,直接寄if(q.isEmpty()) break;// 取最大值加入累计利润w+=q.poll();}return w;}
}

堆一般都用现成的优先队列。

373.查找和最小的K对数字

在这里插入图片描述

class Solution {public List<List<Integer>> kSmallestPairs(int[] nums1, int[] nums2, int k) {int m= nums1.length,n= nums2.length;PriorityQueue<int[]> p=new PriorityQueue<>((a,b)->a[0]-b[0]);List<List<Integer>> ans=new ArrayList<>();for(int i=0;i<Math.min(m,k);i++){//求和,两个数组的索引p.add(new int[]{nums1[i]+nums2[0],i,0});}while(!p.isEmpty() && ans.size()<k){int[] temp=p.poll();int i=temp[1],j=temp[2];ans.add(List.of(nums1[i],nums2[j]));if(j+1< n) p.add(new int[]{nums1[i]+nums2[j+1],i,j+1});}return ans;}
}

比如nums1={1,2,3,4,5}. nums2={6,7,8,9,10}
先把[1,6],[2,6],[3,6],[4,6],[5,6]塞入到优先队列里。
每次出来一个就选择(i,j+1)塞入队列,比如[1,6]出来了就塞入[1,7]
如果不想提前塞入[2,6]这后面四个的话,可以选择当弹出 j=0的时候同时塞入(i,j+1)和(i+1,j)
本质上就是一个Nums1和nums2的矩阵,要不先把第一列塞入,每次塞入(弹出数据右边的)
要不只塞左上角一个,如果弹出的是第一列的,还要再多塞入一个下一行的最左边的。
在while代码添加下面一行即可:
if(j==0 && i+1<m) p.add(new int[]{nums1[i+1]+nums2[0],i+1,0});
总代码如下:

class Solution {public List<List<Integer>> kSmallestPairs(int[] nums1, int[] nums2, int k) {int m= nums1.length,n= nums2.length;PriorityQueue<int[]> p=new PriorityQueue<>((a,b)->a[0]-b[0]);List<List<Integer>> ans=new ArrayList<>();//求和,两个数组的索引p.add(new int[]{nums1[0]+nums2[0],0,0});while(!p.isEmpty() && ans.size()<k){int[] temp=p.poll();int i=temp[1],j=temp[2];ans.add(List.of(nums1[i],nums2[j]));if(j+1< n) p.add(new int[]{nums1[i]+nums2[j+1],i,j+1});if(j==0 && i+1<m) p.add(new int[]{nums1[i+1]+nums2[0],i+1,0});}return ans;}
}

295.数据流的中位数

在这里插入图片描述
左边维持一个大根堆,右边维持一个小根堆。保持两个堆的大小基本一样,相差不超过1

class MedianFinder {//我们尽量让A的元素多一个Queue<Integer> A, B;public MedianFinder() {A = new PriorityQueue<>(); // 小顶堆,保存较大的一半B = new PriorityQueue<>((x, y) -> (y - x)); // 大顶堆,保存较小的一半}public void addNum(int num) {if(A.size() !=B.size()){A.add(num);B.add(A.poll());}else{B.add(num);A.add(B.poll());}}public double findMedian() {return A.size() != B.size() ? A.peek() : (A.peek() + B.peek()) / 2.0;}
}

如果最终是A添加新的数字,这个数字要先在B里过一圈。反之亦然。

108.将有序数组转换为二叉搜索树

在这里插入图片描述
取中间节点当root,然后依次递归左右子树即可。

class Solution {public TreeNode sortedArrayToBST(int[] nums) {return dfs(nums,0,nums.length-1);}public TreeNode dfs(int[] nums,int l ,int r){if(l>r) return null;int mid=(l+r)/2;TreeNode cur=new TreeNode(nums[mid]);cur.left = dfs(nums,l,mid-1);cur.right=dfs(nums,mid+1,r);return cur;}
}

148.排序链表

在这里插入图片描述
用一个归并排序。时间复杂度O(NlogN)。
对数组做归并排序的空间复杂度为 O(n),分别由新开辟数组 O(n)和递归函数调用 O(logn) 组成,而根据链表特性:

数组额外空间:链表可以通过修改引用来更改节点顺序,无需像数组一样开辟额外空间;
递归额外空间:递归调用函数将带来 O(logn) 的空间复杂度,因此若希望达到 O(1) 空间复杂度,则不能使用递归。

    public ListNode sortList(ListNode head) {if(head==null || head.next==null) return head;//一定要讲fast设置为head.next而不是head。不然slow.next=null这一步不好做ListNode slow=head,fast=head.next;while(fast!=null && fast.next!=null){slow=slow.next;fast=fast.next.next;}ListNode dummy=new ListNode(0);ListNode cur=dummy;ListNode temp=slow.next;//将其拆为左右两部分slow.next=null;//左右两部分分别排序ListNode left=sortList(head);ListNode right=sortList(temp);while(left!=null&& right!=null){if(left.val<right.val){cur.next=left;left=left.next;}else{cur.next=right;right=right.next;}cur=cur.next;}//最后肯定有一个为null,直接全部接收后续的cur.next = left!=null? left:right;return dummy.next;}

427.建立四叉树

什么勾八题,题干太长了。肯定不会被考面试。

23.合并K个升序链表

在这里插入图片描述
思考1:暴力,每次遍历k个求最小值。
但是下面的写法是错误的

class Solution {public ListNode mergeKLists(ListNode[] lists) {int k = lists.length;ListNode dummyHead = new ListNode(0);ListNode tail = dummyHead;while (true) {ListNode minNode = null;//int minPointer = -1;for (int i = 0; i < k; i++) {if (lists[i] == null) {continue;}if (minNode == null || lists[i].val < minNode.val) {minNode = lists[i];}}if (minNode==null) {break;}tail.next = minNode;tail = tail.next;minNode=minNode.next;}return dummyHead.next;}}

因为minNode=minNode.next并不能让链表的头结点删除掉。还是要用索引
lists[minPointer]=lists[minPointer].next;

class Solution {public ListNode mergeKLists(ListNode[] lists) {int k = lists.length;ListNode dummyHead = new ListNode(0);ListNode tail = dummyHead;while (true) {ListNode minNode = null;int minPointer = -1;for (int i = 0; i < k; i++) {if (lists[i] == null) {continue;}if (minNode == null || lists[i].val < minNode.val) {minNode = lists[i];minPointer=i;}}if (minNode==null) {break;}tail.next = minNode;tail = tail.next;lists[minPointer]=lists[minPointer].next;}return dummyHead.next;}}

思考2:用一个大小为K的堆,代替每次遍历K次。

class Solution {public ListNode mergeKLists(ListNode[] lists) {int k = lists.length;ListNode dummyNode = new ListNode(0);ListNode tail = dummyNode;Queue<ListNode> q = new PriorityQueue<>((v1, v2) -> v1.val - v2.val);for (ListNode node : lists) {if (node != null) {q.add(node);}}while (!q.isEmpty()) {ListNode temp = q.poll();tail.next = temp;tail = tail.next;if (temp.next != null)q.add(temp.next);}return dummyNode.next;}}

思考3:两两合并,经典分治.
用非递归的方法合并两个链表。用递归的方法合并N个链表。

class Solution {public ListNode merge2Lists(ListNode l1,ListNode l2){ListNode dummyNode =new ListNode(0);ListNode temp=dummyNode;while(l1!=null && l2!=null){if(l1.val<l2.val){temp.next=l1;l1=l1.next;}else{temp.next=l2;l2=l2.next;}temp=temp.next;}temp.next= l1!=null? l1:l2;return dummyNode.next;}public ListNode mergeNLists(ListNode[] lists,int left,int right){if(left==right) return lists[left];int mid=(left+right)/2;ListNode leftMerge=mergeNLists(lists,left,mid);ListNode rightMerge=mergeNLists(lists,mid+1,right);return merge2Lists(leftMerge,rightMerge);}public ListNode mergeKLists(ListNode[] lists) {if(lists.length==0) return null;return mergeNLists(lists,0,lists.length-1);}}

53.最大子数组和

在这里插入图片描述
dp[i]含义,必须用Nums[i]的最大子数组和。截止到i
当然其实如果前面之和是负数,就不用管他。如果是正数,就是dp[i-1]+nums[i];

class Solution {public int maxSubArray(int[] nums) {int[] dp=new int[nums.length];dp[0]=nums[0];int ans=dp[0];for(int i=1;i<nums.length;i++){dp[i]=Math.max(nums[i],nums[i]+dp[i-1]);ans=Math.max(ans,dp[i]);}return ans;}
}

918.环形子数组的最大和

在这里插入图片描述
对于{-1,-1,-1}这种,也要取一个数字。ans=-1
拼接成2倍长度,还要考虑滑动区间大小不能大于n,各种条件太复杂了。
还是直接Math.max(maxSum,sum-minSum);简单。
minSum就是中间的最小的一部分。
6,6,6, -5,-4,-3, 6,6,6

class Solution {public int maxSubarraySumCircular(int[] nums) {int maxSum=nums[0],minSum=nums[0];int maxTemp=0,minTemp=0;int sum=0;for(int i=0;i<nums.length;i++){maxTemp=Math.max(nums[i],maxTemp+nums[i]);maxSum=Math.max(maxSum,maxTemp);minTemp=Math.min(nums[i],minTemp+nums[i]);minSum=Math.min(minSum,minTemp);sum+=nums[i];}return sum==minSum? maxSum:Math.max(maxSum,sum-minSum);}
}

maxSum,截止到当前为止,最大的一段区间和
minSum,截止到当前为止,最小的一段区间和
如何sum==minSum。说明全是负数。则最大的一段区间和就是数组里最大的负数
maxTemp,必须用到nums[i]的最大区间和
minTemp,必须用到nums[i]的最小区间和

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

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

相关文章

Hive on Spark 配置

目录 1 Hive 引擎简介2 Hive on Spark 配置2.1 在 Hive 所在节点部署 Spark2.2 在hive中创建spark配置文件2.3 向 HDFS上传Spark纯净版 jar 包2.4 修改hive-site.xml文件2.5 Hive on Spark测试2.6 报错 1 Hive 引擎简介 Hive引擎包括&#xff1a;MR&#xff08;默认&#xff09…

Go-React做一个todolist(服务端)【一】项目初始化

后端仓库地址 地址 项目依赖 # gin go get -u github.com/gin-gonic/gin # viper日志 go get -u github.com/spf13/viper # 数据库和gorm go get -u gorm.io/driver/mysql go get -u gorm.io/gorm # uuid go get -u github.com/google/uuid # token go get -u github.com/go…

postcss安装和使用(详细)

1,安装postcss&#xff1a; 在此之前需要安装有node.js 第一步 命令&#xff1a;cnpm install postcss-cli -g 第二步 命令&#xff1a;cnpm install postcss –g 推荐内容 2,下载autoprefixer插件&#xff0c;并创建postcss.config.js文件并写入配置代码 autoprefixer插件…

HCIP【GRE VPN、MGRE VPN与PPP验证综合实验】

目录 实验要求&#xff1a; 实验拓扑图&#xff1a; 实验思路&#xff1a; 实验步骤&#xff1a; 一、配IP地址 &#xff08;1&#xff09;配置所有设备接口的IP地址&#xff1a; &#xff08;2&#xff09;配置私网与公网接口的缺省路由使得公网可通&#xff1a; 二、P…

基于boost准标准库的搜索引擎项目

零 项目背景/原理/技术栈 1.介绍boost准标准库 2.项目实现效果 3.搜索引擎宏观架构图 这是一个基于Web的搜索服务架构 该架构优点: 客户端-服务器模型&#xff1a;采用了经典的客户端-服务器模型&#xff0c;用户通过客户端与服务器交互&#xff0c;有助于集中管理和分散计算…

设计模式6--抽象工厂模式

定义 案例一 案例二 优缺点

MacOS M1/M2/M3芯片如何安装Python3.6

前言 Mac电脑M芯片安装Python3.6报错。 一般情况下&#xff0c;Mac系统可以使用homebrew来管理安装软件。 brew search搜索发现&#xff0c;最低只能直接安装python3.7版本。 于是从Python官网下载安装包进行安装&#xff0c;确实也没有报错&#xff0c;安装完成后执行总是k…

【自动装箱以及包装类的缓存】⭐️通过具体案例看下每种包装类的不同结果

目录 前言 一、自动装箱与拆箱&#xff08;以 Integer 包装类为例&#xff09; 二、再来看看几个示例 ​编辑三、Double ,Float 类型亦是如此吗&#xff1f; 前言 小伙伴们大家好&#xff0c;日常使用业务层方面的代码居多&#xff0c;但也不可忘了基本的一些代码格式以及原…

ubuntu22.04@Jetson Orin Nano安装配置VNC服务端

ubuntu22.04Jetson Orin Nano安装&配置VNC服务端 1. 源由2. 环境3. VNC安装Step 1: update and install xserver-xorg-video-dummyStep 2: Create config for dummy virtual displayStep3: Add the following contents in xorg.conf.dummyStep 4: Update /etc/X11/xorg.con…

设计模式7--建造者模式

定义 案例一 案例二 优缺点

面试题1(京东)之HiveSql --- 难度:入门初级

第1题 有如下的用户访问数据 userIdvisitDatevisitCountu012017/1/215u022017/1/236u032017/1/228u042017/1/203u012017/1/236u012017/2/218u022017/1/236u012017/2/224 要求使用SQL统计出每个用户的累积访问次数&#xff0c;如下表所示&#xff1a; 用户id月份小计累积u01…

《云原生安全攻防》-- K8s集群安全风险分析

在这个数字化快速发展的年代&#xff0c;云原生安全变得越来越重要。我明白对于很多朋友来说&#xff0c;这是一个既新奇又复杂的领域。因此&#xff0c;我整合了以往的专业积累&#xff0c;精心打造了一个专门讲解云原生安全的系列课程&#xff0c;目的是能给大家带来有价值的…

微信小程序备案流程详细操作指南

自2023年9月1日起&#xff0c;所有新上架的微信小程序均需事先完成备案手续&#xff0c;方能成功上线。而对于已经上架的存量小程序&#xff0c;也需要在2024年3月31日前完成备案工作。若在规定时间内未完成备案&#xff0c;平台将依据备案相关规定&#xff0c;自2024年4月1日起…

TC16-161T+ 音频 信号变压器 RF Transformers 600kHz-160MHz 射频集成电路 Mini-Circuits

Mini-Circuits是一家全球领先的射频、微波和毫米波元器件及子系统制造商。TC16-161T是Mini-Circuits出产的一款射频IC&#xff08;射频集成电路&#xff09;&#xff0c;具有平衡-不平衡转换器功用。制造商: Mini-Circuits 产品品种: 音频变压器/信号变压器 RoHS…

Git 如何合并多个连续的提交

我平常的编程喜欢是写一段代码就提交一次&#xff0c;本地一般不攒代码&#xff0c;生怕本地有什么闪失导致白干。但这样就又导致一个问题&#xff1a;查看历史日志时十分不方便&#xff0c;随便找一段提交可以看到&#xff1a; > git log --oneline 8f06be5 add 12/qemu-h…

OSPF基本原理和概念

文章目录 背景知识OSPF协议概述&#xff1a;OSPF区域的表示OSPF 骨干区域 –区域0OSPF 非骨干区域 -非0区域OSPF的五种区域类型OSPF工作原理OSPF 的报文类型OSPF邻居表中的七个状态 总结 背景知识 一台路由设备如何获取其他网段的路由&#xff0c;并加入到路由表中 直连路由 …

腾讯云2核2G服务器优惠价格,61元一年

腾讯云2核2G服务器多少钱一年&#xff1f;轻量服务器61元一年&#xff0c;CVM 2核2G S5服务器313.2元15个月&#xff0c;轻量2核2G3M带宽、40系统盘&#xff0c;云服务器CVM S5实例是2核2G、50G系统盘。腾讯云2核2G服务器优惠活动 txybk.com/go/txy 链接打开如下图&#xff1a;…

Etag:HTTP缓存控制机制解析

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 &#x1f35a; 蓝桥云课签约作者、上架课程《Vue.js 和 E…

无论PC还是Mac,都能畅快地使用移动硬盘 Mac使用NTFS移动硬盘不能读写

如果你拥有一台Mac设备&#xff0c;总会遇到尴尬的那一刻——你在Mac上用得好好的移动硬盘怎么都不能被PC识别到。又或者你朋友在PC上用得好好的移动硬盘&#xff0c;连上你的Mac后&#xff0c;Mac里的文件死活就是拷贝不进移动硬盘里。这种坑&#xff0c;相信大多数使用Mac的小…

.NET使用HttpClient以multipart/form-data形式post上传文件及其相关参数

前言&#xff1a; 本次要讲的是使用.Net HttpClient拼接multipark/form-data形式post上传文件和相关参数&#xff0c;并接收到上传文件成功后返回过来的结果&#xff08;图片地址&#xff0c;和是否成功&#xff09;。可能有很多人会说用ajax不是就可以轻松的实现吗&#xff1f…