文章目录
- 引言
 - 正文
 - 第一题:距离为1的字符串
 - 个人实现
 - 修正实现
 
- 第二题:三角形数
 - 个人实现
 - 反思实现
 - 比较对象使用equals
 - Collections.sort方法
 
- 总结
 
引言
- 今天的笔试难度不算大,但是自己的做的很糟糕,发现了很多问题,很多模板记混了!
 
正文
第一题:距离为1的字符串
- 定义字符串S和字符串T的距离为1,满足以下三种情况 
  
- 仅仅修改S的一个字母,就能够和字符串T一摸一样
 - S仅仅增加一个字母,就可以和字符串T一摸一样
 - S仅仅删除一个字母,就可以和字符串T一摸一样
 
 
个人实现
- 这里直接模拟,暴力写的,代码很不美观,具体如下
 
public class Main {
    public boolean editdistance (String s, String t) {
        // write code here
        int count = 1;
        if(s.length() == t.length()){
            // 长度相同,就修改一个字符
            for(int i = 0,j = 0;i < s.length() && j < t.length();i ++,j ++){
                if(s.charAt(i) != t.charAt(j))  count --;
                if(count < 0)   return false;
            }
            return true;
        }
        else if(s.length() < t.length() && s.length() + 1 == t.length()){
            // s比较短,添加一个字符就行
            for(int i = 0,j = 0;i < s.length() && j < t.length();){
                if(s.charAt(i) == t.charAt(j))  {
                    i ++;
                    j ++;
                }
                else{
                    if(count <= 0)    return false;
                    else{
                        // 不相等的情况下的
                        count --;
                        j++;
                    }
                }
                return true;
            }
        }
        else if(s.length() > t.length() && s.length() - 1 == t.length()){
            // s比较长,删除任意一个字符即可
            for(int i = 0,j = 0;i < s.length() && j < t.length();){
                if(s.charAt(i) == t.charAt(j)) {
                    i++;
                    j ++;
                }
                else{
                    if(count <= 0)    return false;
                    else{
                        // 不相等的情况下的
                        count --;
                        i ++;
                    }
                }
                return true;
            }
        }
        return false;
    }
    public static void main(String[] args) {
        System.out.println("Hello world!");
    }
}
 
- 只能通过百分之九十的样例
 
修正实现
长度相同,用一个索引即可
 
 逻辑重复,这里仅仅针对长度大于一的情况
 
public class Main {
    public boolean editdistance (String s, String t) {
        // write code here
        int count = 1;
        if(s.length() == t.length()){
            // 长度相同,就修改一个字符
            for(int i = 0;i < s.length() ;i ++){
                if(s.charAt(i) != t.charAt(i))  count --;
                if(count < 0)   return false;
            }
            return true;
        }
        else if(s.length() + 1 == t.length()){
            // s比较短,添加一个字符就行
            for(int i = 0,j = 0; j < t.length(); j ++){
                if(i < s.length() && s.charAt(i) == t.charAt(j))
                    i ++;
                else
                    count --;
                if(count < 0)    return false;
            }
            return true;
        }
        else if(s.length() - 1 == t.length()){
            // s比较长,删除任意一个字符即可
            for(int i = 0,j = 0; i < s.length();i ++ ){
                if(j < t.length() && s.charAt(i) == t.charAt(j)) 
                    j ++;
                else
                    count --;
                if (count < 0)
                    return false;
            }
            return true;
        }
        return false;
    }
    public static void main(String[] args) {
        System.out.println("Hello world!");
    }
}
 
发现我总是把不同的逻辑糅杂在一块,其实这个习惯很差,完全么有必要这样,代码不好写,而且容易出错,完全没有必要这样!
第二题:三角形数
- 给你n个数字(n>=3),然后找出其中特殊三角形,该特殊三角形定义如下 
  
- 不能是等边三角形
 - 不能是直角三角形
 - 必须是三角形
 
 - 返回能够构成这个三角形的组合数量,是以索引为区分单位,并不是以具体数值为区分单位,所以即使排列的元素数值相同,也算作是两个。
 
个人实现
- 这道题明着看,就是一道组合数,可以直接使用三层循环进行遍历,但是还是只能通过5%的样例,我本来使用回溯写的,但是写的太糟糕了,搞混了,没记住,每一次遍历的时候,应该就是遍历对应两种情况,存在或者不存在就行了,没有必要的在遍历剩余所有的元素了,这里写错了。
 
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class Main {
    static int count;
    static List<Integer> list;
    static boolean check(){
        Collections.sort(list);
        // 等边三角形
        if(list.get(0) == list.get(1) && list.get(0) == list.get(1) )   return false;
        // 直角三角形
        float ab = list.get(0) * list.get(0) +  list.get(1) * list.get(1);
        float c = list.get(2) * list.get(2);
        if (ab == c)    return false;
        // 判定三角形
        boolean cond1 = list.get(1) + list.get(0) > list.get(2);
        boolean cond2 = list.get(2) + list.get(0) > list.get(1);
        boolean cond3 = list.get(1) + list.get(2) > list.get(0);
        if(cond1 && cond2 &&cond3) return true;
        return false;
    }
    static void dfs(int[] length,int idx){
        // 终止条件
        if(list.size() == 3 && check()){
            count ++;
            return;
        }
        if(idx == length.length)    return;
        // 迭代条件
        for(int i :length){
            // 当前元素不添加
            dfs(length,idx + 1);
            list.add(i);
            dfs(length,idx + 1);
            list.removeLast();
        }
    }
    static int happyTriangle (int[] length) {
        list = new ArrayList<>();
        count = 0;
        dfs(length,0);
        return count;
    }
    public static void main(String[] args) {
        int[] temp = {5,3,4,6,6,1};
        System.out.println(happyTriangle(temp));
    }
}
 
改变的list的元素顺序后,并没有恢复现场,导致情况异常
 
 判定Integer对象是否相等用==,超过127就出错

 最终修改如下,这个代码写的确实不行,这里纠正了,下次绝对不会再犯了!
 
反思实现
- 这里编程的思路不够明确,这道题明确就是先套一个完全组合的模板,然后再实现一个三角形过滤函数就行了,但是编程的时候出现了很多问题,确实不应该!
 - 这里在对上述代码整理一下,具体实现如下
 
import javax.swing.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class Main {
    static int count;
    static List<Integer> list;
    static boolean check(){
        int a = Math.max(list.get(0),Math.max(list.get(1),list.get(2)));
        int b = Math.min(list.get(0),Math.min(list.get(1),list.get(2)));
        int c = list.get(0) + list.get(1) + list.get(2) - a - b;
        // 判定直角三角形
        if(b * b + c * c == a * a) return false;
        // 判定等边三角形
        if(a == b && b == c) return false;
        // 判定是三角形
        if(b + c <= a)  return false;
        return true;
    }
    static void dfs(int[] length,int idx){
        // 迭代终止的条件
        if (idx == length.length){
            System.out.println(list);
            if (list.size() == 3 && check()){
                count ++;
            }
            return ;
        }
        // 每一次迭代内容,每一个元素是否有两种情况
        // 不放入对应的元素
        dfs(length,idx + 1);
        // 放入对应的元素
        if(list.size() < 3) {
            list.add(length[idx]);
            dfs(length, idx + 1);
            list.remove(list.size() - 1);
        }
    }
    static int happyTriangle (int[] length) {
        count = 0;
        list = new ArrayList<>();
        dfs(length,0);
        return count;
    }
    public static void main(String[] args) {
        int[] temp = {5,3,4,6,6,1};
        System.out.println(happyTriangle(temp));
    }
}
//[3, 4, 6]
//[3, 4, 6]
//[4, 6, 6]
//[1, 6, 6]
//17
 
比较对象使用equals
==
- 默认是比较两个对象引用是否指向同一个内存地址
 - 对于基本数据类型(int,char)比较的是值,对于应用类型(integer,character)比较的是引用的地址
 
equals
- 默认情况下比较的是对象的引用
 - 很多类比如integer等都重写了该方法,比较的是对象的内容
 
Integer对象的特殊情况
- Integer是有一个缓存范围,-128到127,在这个范围内的Integer对象是缓存的,如果两个Integer对象的值在这个范围内值相同,实际是引用同一个对象。
 - 在这个范围内,equal和==的结果是相同的
 
比较值的话,还是使用equal进行比较
Collections.sort方法
- Collections.sort会改变原来的list内部的元素的内容,我的代码中就有这个问题,改变了原来代码中的元素顺序,然后在弹出就不是原来的位置了!
 
总结
-  
这两道题虽然是比较简单,但是我做的并不好,并没通过所有的样例,但是学到了很多东西,纠正了很多以前做题的坏习惯,总结一下,具体如下
- 判断引用对象相等用equal
 - 使用完Collections.sort记得恢复现场
 
 -  
后续在加油!今天很棒!
 



















