2022-11-19
牛客-面试高频榜单
2 简单 3 中等 1困难
76 两个栈来实现一个队列
用两个栈来实现一个队列,使用n个元素来完成 n 次在队列尾部插入整数(push)和n次在队列头部删除整数(pop)的功能。 队列中的元素为int类型。保证操作合法,即保证pop操作时队列内已有元素。
import java.util.Stack;
public class Solution {
Stack<Integer> stack1 = new Stack<Integer>();
Stack<Integer> stack2 = new Stack<Integer>();
public void push(int node) {
stack1.push(node);
}
public int pop() {
if(stack2.isEmpty()){
while(!stack1.isEmpty()){
stack2.push(stack1.pop());
}
}
return stack2.pop();
}
}
68 跳台阶
一只青蛙一次可以跳上1级台阶,也可以跳上2级。求该青蛙跳上一个 n 级的台阶总共有多少种跳法(先后次序不同算不同的结果)。
import java.util.*;
public class Solution {
public int jumpFloor(int target) {
if(target==1 || target==2) return target;
int f1 = 1;
int f2 = 2;
for(int i=3 ; i<=target ; i++){
int f = (f1+f2);
f1 = f2;
f2 = f;
}
return f2;
}
}
3 链表中环的入口结点
给一个长度为n链表,若其中包含环,请找出该链表的环的入口结点,否则,返回null。
/*
public class ListNode {
int val;
ListNode next = null;
ListNode(int val) {
this.val = val;
}
}
*/
public class Solution {
public ListNode EntryNodeOfLoop(ListNode pHead) {
if (pHead==null) return null;
ListNode fast = pHead;
ListNode slow = pHead;
while(fast!=null && fast.next!=null){
fast = fast.next.next;
slow = slow.next;
if(slow==fast) break;
}
if(fast==null || fast.next==null) return null;
fast = pHead;
while(fast!=slow){
fast = fast.next;
slow = slow.next;
}
return fast;
}
}
53 删除链表的倒数第 n 个节点
给定一个链表,删除链表的倒数第 n 个节点并返回链表的头指针
例如,
给出的链表为: 1→2→3→4→5, n= 2.
删除了链表的倒数第 n个节点之后,链表变为1→2→3→5.
备注:
题目保证 n一定是有效的
import java.util.*;
public class Solution {
public ListNode removeNthFromEnd (ListNode head, int n) {
//添加表头
ListNode res = new ListNode(-1);
res.next = head;
//当前节点
ListNode cur = head;
//前序节点
ListNode pre = res;
ListNode fast = head;
//快指针先行n步
while(n != 0){
fast = fast.next;
n--;
}
//快慢指针同步,快指针到达末尾,慢指针就到了倒数第n个位置
while(fast != null){
fast = fast.next;
pre = cur;
cur = cur.next;
}
//删除该位置的节点
pre.next = cur.next;
//返回去掉头
return res.next;
}
}
1 大数加法
以字符串的形式读入两个数字,编写一个函数计算它们的和,以字符串形式返回。
import java.util.*;
public class Solution {
public String solve (String s, String t) {
//若是其中一个为空,返回另一个
if(s.length()<=0)
return t;
if(t.length()<=0)
return s;
//让s为较长的,t为较短的
if(s.length() < t.length()){
String temp = s;
s = t;
t = temp;
}
int carry = 0; //进位标志
char[] res = new char[s.length()];
//从后往前遍历较长的字符串
for(int i = s.length() - 1; i >= 0; i--){
//转数字加上进位
int temp = s.charAt(i) - '0' + carry;
//转较短的字符串相应的从后往前的下标
int j = i - s.length() + t.length();
//如果较短字符串还有
if(j >= 0)
//转数组相加
temp += t.charAt(j) - '0';
//取进位
carry = temp / 10;
//去十位
temp = temp % 10;
//修改结果
res[i] = (char)(temp + '0');
}
String output = String.valueOf(res);
//最后的进位
if(carry == 1)
output = '1' + output;
return output;
}
}
128 接雨水问题
给定一个整形数组arr,已知其中所有的值都是非负的,将这个数组看作一个柱子高度图,计算按此排列的柱子,下雨之后能接多少雨水。(数组以外的区域高度视为0)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FCymiFfO-1668825521528)(C:\Users\26414\AppData\Roaming\Typora\typora-user-images\image-20221119103034867.png)]
import java.util.*;
public class Solution {
public long maxWater (int[] arr) {
//排除空数组
if(arr.length == 0)
return 0;
long res = 0;
//左右双指针
int left = 0;
int right = arr.length - 1;
//中间区域的边界高度
int maxL = 0;
int maxR = 0;
//直到左右指针相遇
while(left < right){
//每次维护往中间的最大边界
maxL = Math.max(maxL, arr[left]);
maxR = Math.max(maxR, arr[right]);
//较短的边界确定该格子的水量
if(maxR > maxL)
res += maxL - arr[left++];
else
res += maxR - arr[right--];
}
return res;
}
}