299. 猜数字游戏
解法一、遍历+计数
如果是公牛数,A++,剩余的部分都一定是位置不对的。如果是奶牛数,取a计数和b计数里较小的数字、即两字符串出现频数的重叠部分即可
class Solution {
public String getHint(String secret, String guess) {
int A = 0;
int B = 0;
int[] a = new int[10];
int[] b = new int[10];
int len = secret.length();
for(int i = 0;i< len;i++){
if(secret.charAt(i) == guess.charAt(i)){
A++;
}else{
a[secret.charAt(i) - '0']++;
b[guess.charAt(i)-'0']++;
}
}
for(int i = 0;i<=9;i++){
B+= Math.min(a[i],b[i]);
}
return A+"A"+B+"B";
}
}
412. Fizz Buzz
方法一、遍历,分情况讨论
class Solution {
public List<String> fizzBuzz(int n) {
List<String> Arr=new ArrayList<>();
for(int i=1;i<=n;i++){
if(i%3==0 && i % 5 == 0){
Arr.add("FizzBuzz");
}else if(i%3==0){
Arr.add("Fizz");
}else if(i%5==0){
Arr.add("Buzz");
}else{
Arr.add(String.valueOf(i));
}
}
return Arr;
}
}
506. 相对名次
解法一、排序再标记
其实我用了哈希表。但这个不需要精确查取,数组已经够了
class Solution {
public String[] findRelativeRanks(int[] score) {
int n = score.length;
String[] desc = {"Gold Medal", "Silver Medal", "Bronze Medal"};
int[][] arr = new int[n][2];
for (int i = 0; i < n; ++i) {//存入
arr[i][0] = score[i];
arr[i][1] = i;
}
Arrays.sort(arr, (a, b) -> b[0] - a[0]);//排序
String[] ans = new String[n];//答案
for (int i = 0; i < n; ++i) {
if (i >= 3) {
ans[arr[i][1]] = Integer.toString(i + 1);
} else {
ans[arr[i][1]] = desc[i];
}
}
return ans;
}
}
作者:力扣官方题解
链接:https://leetcode.cn/problems/relative-ranks/solutions/1131693/xiang-dui-ming-ci-by-leetcode-solution-5sua/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
539. 最小时间差
解法一、转换单位、排序再比较
字符串无法比对,所以先转换成数字,然后求排序后数组最小值。因为时间是个环,需要考虑一下结尾(1440是59*60+59+1)
如果长度>1440,一定有两个数字重合,则直接返回0(这是3ms→2ms的关键
说起来Collections类居然可以排字符串
class Solution {
public static int findMinDifference(List<String> timePoints) {
int len = timePoints.size();
int[] a = new int[len];
int min = Integer.MAX_VALUE;
if (len > 1440) {
return 0;
}
for(int i = 0;i<len;i++){
String time = timePoints.get(i);
a[i] = ((time.charAt(0)-'0')*10 + (time.charAt(1) - '0'))*60 + ((time.charAt(3)-'0')*10 + (time.charAt(4) - '0'));
}
Arrays.sort(a);
for(int i = 1;i < len;i++){
int t = [a[i] - a[i-1];
min = Math.min(min,t);
}
int t = (a[0] - a[len-1] + 1440) % 1440;
min = Math.min(min,t);
return min;
}
}
553. 最优除法
解法一、字符串处理+脑筋急转弯
其实就是在第一个数后面直到最后都括起来,如{1,2,3,4,5,6}就是1/(2/3/4/5/6),本质上是字符串题
不难,因时间大受打击
class Solution {
public static String optimalDivision(int[] nums) {
int len = nums.length;
StringBuffer sb = new StringBuffer();
if(len == 1){
return String.valueOf(nums[0]);
}
sb.append(String.valueOf(nums[0])+"/(");
for(int i = 1;i < len-1;i++){
sb.append(String.valueOf(nums[i])+'/');
}
sb.append(String.valueOf(nums[len-1])+')');
return sb.toString();
}
}
优化后如下,原来不需要String.valueOf,而且也最好不要用字符串拼接(不过为什么,是很花时间吗
class Solution {
public static String optimalDivision(int[] nums) {
int len = nums.length;
StringBuffer sb = new StringBuffer();
if (len == 1) {
return sb.append(nums[0]).toString();
}
if (len == 2) {
return sb.append(nums[0]).append("/").append(nums[1]).toString();
}
sb.append(nums[0]).append("/(");
for(int i = 1;i < len-1;i++){
sb.append(nums[i]).append('/');
}
sb.append(nums[len-1]).append(')');
return sb.toString();
}
}
537. 复数乘法
解法一、转换,处理,直接求
因为num1和num2都是r+i的形式,找到加号,往前处理;往后处理(记得不要算i,所以是len-1)
当然后来发现比起valueOf,parseInt更好
官方用了正则
String[] complex1 = num1.split("\\+|i");
class Solution {
public String complexNumberMultiply(String num1, String num2) {
int r = 0;
int i = 0;
int indexA = num1.indexOf('+');
int rA = Integer.valueOf(num1.substring(0,indexA));
int iA = Integer.valueOf(num1.substring(indexA+1,num1.length()-1));
int indexB = num2.indexOf('+');
int rB = Integer.valueOf(num2.substring(0,indexB));
int iB = Integer.valueOf(num2.substring(indexB+1,num2.length()-1));
r = rA * rB - iA*iB;
i = rA * iB + rB * iA;
StringBuffer sb = new StringBuffer();
return sb.append(r).append('+').append(i).append('i').toString();
}
}
592. 分数加减运算
解法一、先转数字再运算
见注释!
class Solution {
public static String fractionAddition(String expression) {
int len = expression.length();
int num = 0;
for(int i = 0;i < len;i++){//计算一共有多少个分数,存作num
if(expression.charAt(i) == '/')num++;
}
int[][] a = new int[num][2];
if(num == 1){
return expression;
}
String[] fractions = expression.split("(?=[-+])");//正则分割开
int temp = 1;
for(int i = 0;i < num;i++){//0存分子,1存分母
int index = fractions[i].indexOf('/');
a[i][0] = Integer.parseInt(fractions[i].substring(0,index));
a[i][1] = Integer.parseInt(fractions[i].substring(index+1));
temp*= a[i][1];//分母的累乘
}
int sum = 0;
for(int i = 0;i < num;i++){//sum+=分子*相差倍数
sum+= a[i][0] * (temp/a[i][1]);
}
int t = Math.abs(gcd(sum,temp));//最大公约数
sum/=t;//处理分子与分母
temp/=t;
StringBuffer sb = new StringBuffer();
sb.append(sum).append('/').append(temp);
return sb.toString();
}
public static int gcd(int a, int b) {
if (b == 0) {
return a;
}
return gcd(b, a % b);
}
}
640. 求解方程
解法一、模拟
太难了没敲出来。。有点复杂。循环遍历原字符串转为数字,'+'‘-’的时候变符号,x是x系数,num是常数,‘=’的时候翻转模拟变号。最后讨论。
class Solution {
public String solveEquation(String s) {
int x = 0, num = 0, n = s.length();
char[] cs = s.toCharArray();
for (int i = 0, op = 1; i < n; ) {
if (cs[i] == '+') {
op = 1; i++;
} else if (cs[i] == '-') {
op = -1; i++;
} else if (cs[i] == '=') {
x *= -1; num *= -1; op = 1; i++;
} else {
int j = i;
while (j < n && cs[j] != '+' && cs[j] != '-' && cs[j] != '=') j++;
if (cs[j - 1] == 'x') x += (i < j - 1 ? Integer.parseInt(s.substring(i, j - 1)) : 1) * op;
else num += Integer.parseInt(s.substring(i, j)) * op;
i = j;
}
}
if (x == 0) return num == 0 ? "Infinite solutions" : "No solution";
else return "x=" + (num / -x);
}
}
作者:宫水三叶
链接:https://leetcode.cn/problems/solve-the-equation/solutions/1736347/by-ac_oier-fvee/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
38. 外观数列
解法一、模拟遍历
class Solution {
public static String countAndSay(int n) {
return RLE("1",n);
}
public static String RLE(String a,int num){
if(num==1)return a;
int len = a.length();
StringBuffer sb = new StringBuffer();
int ptr = 0;
while(ptr<len){
int count = 1;
while (ptr<len-1 && a.charAt(ptr) == a.charAt(ptr+1)){
ptr++;//统计数量用
count++;
}
sb.append(count);
sb.append(a.charAt(ptr));
ptr++;
}
return RLE(sb.toString(),--num);
}
}
感觉这么写更正统一些
class Solution {
public String countAndSay(int n) {
if (n == 1) {
return "1";
}
String s = countAndSay(n - 1);
StringBuilder sb = new StringBuilder();
for (int i = 0; i < s.length();) {
char c = s.charAt(i);
int count = 0;
while (i < s.length() && s.charAt(i) == c) {
count++;
i++;
}
sb.append(count).append(c);
}
return sb.toString();
}
}
解法二、打表
不必多说jpg
碎碎念
- 学会了降序数组的比较器写法 Arrays.sort(arr, (a, b) -> b[0] - a[0]);
- 对于539,强调了len最开始可以滤掉一部分特殊情况,对优化时间来说很重要
- 熟悉了while+ptr遍历字符串转换的流程,对0和len-1的了解也纯熟很多
- 写秃了 640是真复杂啊 兄弟
- ↓是Collections类