1.猜字母
思路1:采用字符串形式
public class 猜字母 {
public static void main(String[] args) {
StringBuilder a=new StringBuilder("abcdefghijklmnopqrs");
//StringBuilder效率更高
for (int i = 1; i <106 ; i++) {
a.append("abcdefghijklmnopqrs");
}
//重复拼接获得子串
while (a.length()>1){
int l=a.length()/2;
if (a.length()%2!=0) {
l++;
}
for (int i = 0; i <l; i++) {//注意这里是i++不是i+=2,因为待删除的数组下标在变化
a.deleteCharAt(i);
}
}
System.out.println(a);//q
}
}
🔑解析:首先这里我们用的是StringBuider,因为它的效率是最高的。这里我们才用字符串的一个好处是它自带的delete操作可以帮助我们删除元素,但正因如此也是我们容易掉坑的地方。当我们删除一个元素后,后续的元素会马上排上来,导致我们本该删除的元素的下标变化,导致了删掉了错误的元素。但其实也是有规律的,每删除一个元素后,后续所有待删除的元素都向左移动一格。比如有个字符串abcde,按照要求我们需要删掉ace这三个,a的下标为0删除后,原字符串变为bcde,这时本来下标为2的c变成了1,这时我们删掉c后再下一个待删除的元素e下标变为2了。于是本来需要隔一个再删除,却由于下标动态变化就只需要让i++而不是i+=2了。这里只需要考虑到长度为奇数时需要比偶数多删一次的问题即可,最后删剩的字符就是q。
思路2:采用数组形式
public class 猜字母02 {
public static void main(String[] args) {
char[] a=new char[2014];
int index=0;
for (int i = 0; i < 106; i++) {
for (int j = 0; j < 19; j++) {
a[index++]= (char) ('a'+j);//这里涉及到ascii表的字母转换
}
}
//采用数组形式存放
int len=2014;
while (len!=1){
int k=0;
for (int i = 1; i <len ; i+=2) {
a[k++]=a[i];
}
len=k;
}
System.out.println(a[0]);//q
}
}
🔑解析:用数组形式来做的话更好理解也不容易出错。把每次需要留下来的元素往前摆。用len来动态地保存这一段的长度,k是待插入的下标。每次需要保存的元素往前放,然后用len更新保留下来的数组长度,一次次往前移动,不要的元素放数组后面。最后循环结束后,数组的第一个元素就是我们剩下的元素q。