1. 程式人生 > >java實現:2018年9月7日下午的科大訊飛筆試題:平安夜殺手

java實現:2018年9月7日下午的科大訊飛筆試題:平安夜殺手

下邊是自己理解的解答,如果有問題歡迎指出。

java實現:2018年9月7日下午的科大訊飛筆試題:平安夜殺手

題目:(這裡是按照原題打字的)

有n個殺手排成一行,每一個殺手都有不同的編號(編號為1~n),在每個夜晚殺手都會行動,如果殺手編號大於他右邊的殺手的編號,他就會殺死他右邊的殺手,殺手的行動是瞬間的,所以一個人可能在某一個夜晚既殺死了別人,又被別人殺死。例如3 2 1這個順序,在第一個夜晚2會殺死1,同時3也會殺死2.顯而易見,一段時間後,就不會有人殺或者被殺了,平安夜也就到來了,請問在平安夜之前有多少個夜晚。

輸入說明:(按照原題打字的)

第一行是一個整數n,表示殺手的數量

接下來一行有n個數,是一個1~n的全排列

輸出說明:(按照原題打字的)

輸出包含一個整數,表示平安夜之前經歷的多少個夜晚

樣例一:

樣例輸入:

10

10 9 7 8 6 5 3 4 2 1

樣例輸出:

2

對樣例一的說明:樣例一中殺手變化為[10 9 7 8 6 5 3 4 2 1]->[10 8 4]->[10]

下邊樣例二:

樣例輸入:

6

1 2 3 4 5 6 

樣例輸出:

0

我的理解:

平安夜到來是因為所有殺手順序都是從小到大了,有兩種情況:1)只剩一個;2)類似1 2 3這種都是從小到大的順序。

出現以上兩種情況,就不需要繼續殺人了。一晚只能殺相鄰右邊的殺手。

上邊問題就轉化為:需要殺幾個晚上,才可以把殺手序號變為上邊兩種情況?

解題思路:把殺手編號按照輸入順序放入到list中,看是否滿足上邊的兩種情況,如果滿足,就停止了,如果不滿足,就從後往前比較,如果相鄰的後一個比前一個小,就remove掉後面一個,然後依次往前。遍歷完一次,就相當於過了一個夜晚。一直遍歷直到滿足上邊兩種情況為止。遍歷一次for迴圈就k++一次,這樣來計數。

那麼怎麼判斷是否滿足上邊兩種情況呢?

第一種情況很好判斷,如果只剩一個殺手了,那麼list.size()是為1

第二種情況,如果序列滿足第二種情況,那麼,我們經歷一次for迴圈,我們list.size()大小不變(因為如果是按照從小到大順序排列,list裡面就沒有元素會被remove掉),如果list.seze()在for迴圈前後相等,那麼就使用break退出這個迴圈

我的程式碼:

package test20190907;

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

public class Main {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		List<Integer> list = new ArrayList<Integer>();
		while (sc.hasNext()) {
			int n = sc.nextInt();
			for (int i = 0; i < n; i++) {
				list.add(sc.nextInt());
			}
			// 呼叫一個函式:
			int result = f(list, n);
			System.out.println(result);
		}
	}

	private static int f(List<Integer> list, int n) {
		/*下邊註釋是對這個函式下邊的迴圈和判斷等做說明。
		 * 利用k來計數,就是迴圈的次數,只要while迴圈一次,就計數一次 
		 * (看if中:
		 *  為什麼要有這個判斷?,
		 * 考慮到如果list是按照從小到大的順序, 
		 * 那麼我們k就不用計數 了, 同時直接跳出我們的while迴圈) 
		 * ( 看else中:
		 * 由於上邊的if的判斷,
		 *  需要把本次list.size()和 上次的list.size()做比較
		 * 這裡n,在if中就是表示前一次的list.seze();)
		 */
		// TODO Auto-generated method stub
		int k = 0;
		while (list.size() > 1) {
			for (int i = list.size() - 1; i >= 1; i--) {
				if (list.get(i) < list.get(i - 1)) {
					list.remove(i);
					// i++;
				}
			}
			if (list.size() == n) {// 這裡n表示迴圈前的list.size();
				break;
			} else {
				n = list.size();
				k++;
			}
		}
		return k;
	}
}

控制檯:(這裡輸入了三組)包括題目中給出的輸入輸出例子)