題目不能完整的記下來,目測後面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給的題目中,代碼很多,所以我這裏也寫得比較多。