第一题 旋转字符串
1.题目要求
2. 思路分析
难度:Easy
(1)首先分析一共是4*K个字符,需要拼成的矩形字符是K+1行,且每行K+1个字符;
(2)按照行分类:第1行和K+1行比较特殊,需要单独实现;第2-K行规律类似,看成一种情况,共三种情况分析:line=1;line=K+1;1<line<K+1;(代码中行号从0开始);
(3)第 1行:nums[0]---nums[K];第K+1行:nums[2*K]--nums[3*K]逆序;
第2-K行:nums[len-lineNum+1],K-1个空格,nums[K+lineNum-1]
3. Java代码
public class Main{
/**
* the first problem
* 旋转的字符串
*/
public static void main_first(String[] args) {//运行时去掉_first
Scanner scanner = new Scanner(System.in);
String str = scanner.nextLine();
char[] chars = str.toCharArray();
int K = chars.length/4;
char[] spaces = new char[K-1];
for(int i = 0;i<K-1;i++){
spaces[i] = ' ';
}
String spaceStr = new String(spaces);
for(int i = 0;i < K+1;i++){//控制行数
if(i == 0){
System.out.println(str.substring(0,K+1));
}else if(i >0 && i < K){
System.out.println(chars[4*K-i]+spaceStr+chars[K+i]);
}else{
System.out.println(new StringBuilder(str.substring(2*K,3*K+1)).reverse().toString());
}
}
}
}
第二题 有趣的变换
1. 题目要求
2.分析思路
难度:Medium
第二种:优化思路(先看第一种)
提供halfCount函数,统计当前段的符合规范的情况。
首先:一位数,返回1;
若开头和结尾都是0,则返回0;
若开头或结尾有一个为0,则返回1;因为开头为0,只能为0.xxx;结尾为0,只能为整数;
最后,可能情况就是字符的个数,如203:203,2.03,20.3
第一种:笨重思路
(1)首先将整数字符串转换成字符数组char[] nums,其长度为len;
(2)遍历分割方式:[1,len-1]、[2,len-2].....、[len-1,1];
(3)在上述的每一种情况下,分别计算前一段、后一段符合规则的数目preCount和sufCount,然后将preCount*sufCount乘积累加起来;输出sum即为答案。
(4)分割方式采用遍历方法,对于分割后的一段,由于小数点的移动会带来多种可能,因此构建一个方法isLegal用来判断当前小数点下是否合法:boolean isLegal(char[] nums,int from ,int end,int point);具体实现思路:
首先判断是否是一位数,若是一位数,返回true;
再判断是否是多位整数:若是多位整数且不以0开头,则返回true;否则返回false;
最后判断小数:小数以0结尾,必须为false;小数若以0开头必须是0.xxx,若为0.xxx返回true,否则返回false。
3. Java代码
优化算法:
/**
* the second problem
* 有趣的变换
* 比较优化的方法
*/
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String numStr = scanner.nextLine();
char[] nums = numStr.toCharArray();
int count = 0;
for(int i = 0;i < nums.length-1;i++){
int leftCount = halfCount(nums,0,i);
if(leftCount == 0) continue;//提高效率;左段不存在;右段就不用统计了
int rightCount = halfCount(nums,i + 1,nums.length-1);
count += leftCount*rightCount;
}
System.out.println(count);
}
public static int halfCount(char[] nums,int from ,int end){
if(from == end) return 1;//一位数肯定就一种
if(nums[from] == '0'&& nums[end] == '0') return 0;//前后都有0,肯定不合法
if(nums[from] == '0'|| nums[end] == '0') return 1;//以0开头只能为0.xxx;以0结尾只能为整数
return end-from+1;//如345,:345,3.45,34.5
}
第一种方法:笨重
public class Main{
/**
*the second problem
* 有趣的变换
*/
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String numStr = scanner.nextLine();
char[] nums = numStr.toCharArray();
int count = 0;
int len = nums.length;
for(int i = 0;i < len -1;i++){//从[1,len-1],[2,len-2],...,[len-1,1]
int preCount = 0,sufCount = 0;
for(int point = -1;point < i; point ++) {
if (isLegal(nums, 0, i, point)) {//前一段可以
preCount ++;
}
}
for(int point2 = i; point2 < len-1;point2++){
if (isLegal(nums, i+1, len-1, point2)){
sufCount++;
}
}
count += preCount*sufCount;
}
System.out.println(count);
}
/**
* 判断nums[from]--nums[end]组成的数字是否合法,point表示小数点位置
* @param nums
* @param from
* @param end
* @param point
* @return
*/
public static boolean isLegal(char[] nums,int from ,int end,int point){
//一位数情况:肯定返回ture;(此时必有point<from,但是point<from不一定只是一位数)
if(from == end) return true;//只有1位数,肯定返回true
//以下是多位数情况
if(point < from) {//多位整数
return nums[from] != '0'? true :false;
}
//下面是小数情况
if(nums[end] == '0'){//如果以0结尾,必定返回false
return false;
}
if(nums[from]=='0'){//如果以0开头,必须0.xxx才可以
if(point != from ) return false;//当前必须是小数点,否则返回false
}
return true;
}
}
第三题 多多社交推荐
1. 题目要求
2. 思路分析
待续.....
3. Java代码
待续.......
第四题 升序降序取数游戏
1. 题目要求
2. 思路分析
待续......
3. Java代码
待续......