题目不能完整的记下来,目测后面vivo会把题目放到牛客上,这里先给一些解析
1、种花问题
刚发现原来是Leetcode上的605题
假设你有一个很长的花坛,一部分地块种植了花,另一部分却没有。可是,花卉不能种植在相邻的地块上,它们会争夺水源,两者都会死去。
给定一个花坛(表示为一个数组包含0和1,其中0表示没种植花,1表示种植了花),和一个数 n 。能否在不打破种植规则的情况下种入 n 朵花?能则返回True,不能则返回False。
示例 1:
输入: flowerbed = [1,0,0,0,1], n = 1
输出: True
示例 2:
输入: flowerbed = [1,0,0,0,1], n = 2
输出: False
注意:
数组内已种好的花不会违反种植规则。
输入的数组长度范围为 [1, 20000]。
n 是非负整数,且不会超过输入数组的大小。
刚开始我以为是动态规划问题,浪费了很多时间,后来发现是一个找规律的问题。
解题思路:
情况1:排除端点
排除端点外,我们假设可以种花的区域被花包围,也就是中间连续的0被1包围。
像下面这种情况,显然是不能种花的
1 0 0 1;
而这种情况:
1 0 0 0 1 可种1朵花
1 0 0 0 0 1 可种1朵花
1 0 0 0 0 0 1 可种2朵花
1 0 0 0 0 0 0 1 可种2朵花
1 0 0 0 0 0 0 0 1 可种3朵花
1 0 0 0 0 0 0 0 0 1 可种3朵花
不难发现,每隔着2个0,就会有多种一朵花的机会。
公式就很好推算了,中间有n个0时,可以种(n-1)/2朵花
情况2:考虑端点
当某个端点为0时,我们可以多种一朵花
1 0 0 可种1朵花
1 0 0 0 可种1朵花
1 0 0 0 0 可种2朵花
1 0 0 0 0 0 可种2朵花
1 0 0 0 0 0 0 可种3朵花
1 0 0 0 0 0 0 0 可种3朵花
情况3:花园大小只有1
当花园大小为1时,我们不能得到一个区间,我们只有一个点,对这个情况要特殊处理
综上所述,我们可以得到以下代码
public static void main(String[] args) {
Scanner in=new Scanner(System.in);
int len=in.nextInt();
int plant[]=new int[len];
int curr=0;
while (curr<len){
plant[curr++]=in.nextInt();
}
slove(plant);
}
private static void slove(int nums[]){
if(nums.length==1){
int x=nums[0]==0?1:0;
System.out.println(x);
return;
}
int slow=0;//0
int quick=0;//1
int count=0;
while (slow<nums.length&&quick<nums.length){
while (slow<nums.length&&nums[slow]==1){
slow++;
}
quick=slow;
while (quick<nums.length&&nums[quick]==0){
quick++;
}
if(quick-slow>=3){
count+=counter(quick-slow);
}
//考虑端节点
if((slow==0||quick==nums.length)&&(quick-slow>=2)){
count++;
}
slow=quick;
}
System.out.println(count);
}
//计算两个空白字符之间的
private static int counter(int sub){
return (sub-1)/2;
}
2、质量测试
题目大意是摔手机,跌落测试来测试手机质量。
这个题就不多说了,一道经典的Leetcode题:Leetcode-887
3、合并流水线
题目大意:
输入:n表示有几条流水线
输出:按照升序排列的,合并后的流水线
很简单,是一个排序问题。不过本题目中要求使用链表。而且源码中还留着一个静态函数,用于合并新输入的链表。
解题思路:使用小顶堆对输入的几条流水线合并,然后弹出,合并到一个流水线中。然后在那个合并函数那里,对两个链表重新合并,按照从小到达插入
public class Main {
private static ListNode dummyNode=new ListNode(-1);
private static ListNode currNode=dummyNode;
public static void main(String[] args) {
currNode=dummyNode;
List<String> lines = new ArrayList<>();
Scanner scanner = null;
try {
scanner = new Scanner(System.in);
int totalLine=Integer.valueOf(scanner.nextLine());
while (totalLine>0) {
lines.add(scanner.nextLine());
totalLine--;
// write your code here
}
PriorityQueue<Integer> queue=new PriorityQueue<>();
for (int i=0;i<lines.size();i++){
String[] nums=lines.get(i).split(" ");
for(String num:nums){
queue.offer(Integer.valueOf(num));
}
}
while (queue.isEmpty()==false){
currNode.next=new ListNode(queue.poll());
currNode=currNode.next;
}
} finally {
if (scanner != null) {
scanner.close();
}
}
// TODO output
ListNode curr=dummyNode.next;
while (curr!=null){
if(curr.next==null){
System.out.print(curr.val);
}else {
System.out.print(curr.val+" ");
}
curr=curr.next;
}
}
static class ListNode {
int val;
ListNode next;
ListNode(int x) {
val = x;
}
}
private static ListNode mergeNodes(ListNode head ) {
dummyNode=merge(dummyNode.next,head);
return dummyNode.next;
}
private static ListNode merge(ListNode n1,ListNode n2){
if(n1==null||n2==null){
return n1==null?n2:n1;
}
ListNode newDummy=new ListNode(-1);
ListNode curr=newDummy;
while(n1!=null&&n2!=null){
int val=n1.val;
if(n1.val>n2.val){
val=n2.val;
n2=n2.next;
}else {
n1=n1.next;
}
curr.next=new ListNode(val);
curr=curr.next;
}
curr.next=n1==null?n2:n1;
return newDummy.next;
}
}
vivo给的题目中,代码很多,所以我这里也写得比较多。