網易校招的一道算法題提到了迴文序列,原題如下:
如果一個數字序列逆置之後跟原序列是一樣的就稱這樣的數字序列爲迴文序列。例如:
{1, 2, 1}, {15, 78, 78, 15} , {112} 是迴文序列,
{1, 2, 2}, {15, 78, 87, 51} ,{112, 2, 11} 不是迴文序列。
現在給出一個數字序列,允許使用一種轉換操作:
選擇任意兩個相鄰的數,然後從序列移除這兩個數,並用這兩個數字的和插入到這兩個數之前的位置(只插入一個和)。
現在對於所給序列要求出最少需要多少次操作可以將其變成迴文序列。
輸入描述
輸入爲兩行,第一行爲序列長度n ( 1 ≤ n ≤ 50)
第二行爲序列中的n個整數item[i] (1 ≤ iteam[i] ≤ 1000),以空格分隔。
輸出描述
輸出一個數,表示最少需要的轉換次數
針對這一道題,我們先從測試用例[1,1,1,3]出發,最差的情況是把相鄰兩個數一直相加,知道只剩下一個數,過程是
原始數據:[1,1,1,3]
第一步: [2,1,3]
第二步: [3,3]
第三步: [6]
觀察過程可知,數據一直在向中間靠攏,實際上不用到第三步,第二步就已經是迴文序列了,那麼迴文序列的標誌是什麼呢?通過觀察可知頭尾相等就是迴文序列,那麼如何通過 [和操作]這一個題目規定的操作來調整成文迴文序列呢,就是比較頭尾一起向中間移動,比較頭部尾部大小,頭部小了,執行頭部相加操作;尾部小了,執行尾部相加操作;當符合迴文序列時,停止計數。
現在來看看我們的實現代碼(Java):
import java.util.Scanner;
public class Main {
public static void main(String[] args){
Scanner scanner = new Scanner(System.in);
while(scanner.hasNext()){
int times = 0;
int n = scanner.nextInt();
int[] inputArr = new int[n];
for(int i = 0; i < n; i++){
inputArr[i] = scanner.nextInt();
}
int head = 0;
int tail = n - 1;
while(head < tail){
if(inputArr[head] > inputArr[tail]){
inputArr[--tail] += inputArr[tail + 1];
times++;
}else if(inputArr[head] < inputArr[tail]){
inputArr[++head] += inputArr[head - 1];
times++;
}else{
head++;
tail--;
}
}
System.out.println(times);
}
scanner.close();
}
}
代碼充分運用了上面的解題思路。