題目要求:java
有一條彩色寶石項鍊,是由不少種不一樣的寶石組成的,包括紅寶石,藍寶石,鑽石,翡翠,珍珠等。有一天國王把項鍊賞賜給了一個學者,並跟他說,你能夠帶走這條項鍊,可是王后很喜歡紅寶石,藍寶石,紫水晶,翡翠和鑽石這五種,我要你從項鍊中截取連續的一小段還給我,這一段中必須包含全部的這五種寶石,剩下的部分你能夠帶走。若是沒法找到則一個也沒法帶走。請幫助學者找出如何切分項鍊纔可以拿到最多的寶石。數組
輸入描述:app
咱們用每種字符表明一種寶石,A表示紅寶石,B表示藍寶石,C表明紫水晶,D表明翡翠,E表明鑽石,F表明玉石,G表明玻璃等等,咱們用一個所有爲大寫字母的字符序列表示項鍊的寶石序列,注意項鍊是首尾相接的。每行表明一種狀況。
輸出描述:spa
輸出學者可以拿到的最多的寶石數量。每行一個
示例1code
ABCYDYE ATTMBQECPD
1
3
初步的解法:求包含ABCDE的最短的子串。首尾相連是爲了不環處理。ip
package snippet; import java.util.Scanner; public class Snippet { public static void main(String[] args) { Scanner in = new Scanner(System.in); while (in.hasNext()) { StringBuffer buff = new StringBuffer(in.nextLine()); buff.append(buff); char s[] = buff.toString().toCharArray(); int length = s.length; int num[] = new int[5]; int min = length / 2; for (int i = 0; i <= length / 2 - 1; i++) { int count = 0; if (s[i] >= 'F') continue; else { for (int j = i; j <= length / 2 + i - 1; j++) { int temp = (int) (s[j] - 'A'); if (temp < 5 && num[temp] == 0) { num[temp]++; count++; } if (count == 5) { min = Math.min(min, j - i + 1); for (int k = 0; k < 5; k++) { num[k] = 0; } break; } } } } System.out.println(length / 2 - min); } } }
本身的代碼中,利用一個整形數組來存放5種目標寶石是否存在的標誌,能夠進一步減小空間複雜度,利用boolean數組,減小爲5個字節;進一步減小能夠利用1個整形數值的5個2進制位來表示是否存在。get
package snippet; import java.util.Scanner; public class Souhu2 { public static void main(String[] args) { Scanner in = new Scanner(System.in); while (in.hasNext()) { StringBuffer buff = new StringBuffer(in.nextLine()); buff.append(buff); //省去環處理 char s[] = buff.toString().toCharArray(); int length = s.length; int min = length / 2; for (int i = 0; i <= length / 2 - 1; i++) { int count = 0; if (s[i] >= 'F') continue; else { for (int j = i; j <= length / 2 + i - 1; j++) { int num = (int) (s[j] - 'A'); if (num < 5) count |= 1 << num; if (count == 31) { min = Math.min(min, j - i + 1); break; } } } } System.out.println(length / 2 - min); } } }
Sourceit