每日算法练习

每日算法

2022.4.10

804. 唯一摩尔斯密码词

难度简单224收藏分享切换为英文接收动态反馈

国际摩尔斯密码定义一种标准编码方式,将每个字母对应于一个由一系列点和短线组成的字符串, 比如:

  • 'a' 对应 ".-"
  • 'b' 对应 "-..."
  • 'c' 对应 "-.-." ,以此类推。

为了方便,所有 26 个英文字母的摩尔斯密码表如下:

[".-","-...","-.-.","-..",".","..-.","--.","....","..",".---","-.-",".-..","--","-.","---",".--.","--.-",".-.","...","-","..-","...-",".--","-..-","-.--","--.."]

给你一个字符串数组 words ,每个单词可以写成每个字母对应摩尔斯密码的组合。

  • 例如,"cab" 可以写成 "-.-..--..." ,(即 "-.-." + ".-" + "-..." 字符串的结合)。我们将这样一个连接过程称作 单词翻译

words 中所有单词进行单词翻译,返回不同 单词翻译 的数量。

示例 1:

输入: words = ["gin", "zen", "gig", "msg"]
输出: 2
解释: 
各单词翻译如下:
"gin" -> "--...-."
"zen" -> "--...-."
"gig" -> "--...--."
"msg" -> "--...--."

共有 2 种不同翻译, "--...-." 和 "--...--.".
class Solution {
     public int uniqueMorseRepresentations(String[] words) {
         //使用hashset进行去重
        HashSet<String> ans = new HashSet<String>();
         //codes存放编码
        String[] codes =new String[]{".-","-...","-.-.","-..",".","..-.","--.","....","..",".---","-.-",".-..","--","-.","---",".--.","--.-",".-.","...","-","..-","...-",".--","-..-","-.--","--.."};
         //用来存放每次译码的结果
        String result = "";
       for(String a:words){
           //每次循环初始化result
            result = "";
            for(int i=0;i<a.length();i++){
                //计算译码的位置
                int j = a.charAt(i) - 'a';
                result += codes[j];
            }
            ans.add(result);
        }
       return ans.size();
    }
} 
780. 到达终点

难度困难246收藏分享切换为英文接收动态反馈

给定四个整数 sx , sytxty,如果通过一系列的转换可以从起点 (sx, sy) 到达终点 (tx, ty),则返回 true,否则返回 false

从点 (x, y) 可以转换(x, x+y) 或者 (x+y, y)

示例 1:

输入: sx = 1, sy = 1, tx = 3, ty = 5
输出: true
解释:
可以通过以下一系列转换从起点转换到终点:
(1, 1) -> (1, 2)
(1, 2) -> (3, 2)
(3, 2) -> (3, 5)

示例 2:

输入: sx = 1, sy = 1, tx = 2, ty = 2 
输出: false
public boolean reachingPoints(int sx, int sy, int tx, int ty) {
            //递归解决
            if(sx==tx&&sy==ty){
                return true;
            }
            //如何判定失败:一个点只能向前走,如果终点在后面,判定失败。
            if(sx<tx||sy<ty){
                return false;
            }
            return reachingPoints(sx+sy,sy,tx,ty) || reachingPoints(sx,sy+sx,tx,ty);

        }

结果执行错误因为一些用例数据过大,导致栈溢出。

正解:逆向思维

//从(tx, ty)推到(sx, sy),则时只能有一种操作,就是将tx、ty中较大值减去较小值(因为顺推的时候是(x, y)
 //可以转换到 (x, x+y) 或者 (x+y, y)

    public boolean reachingPoints(int sx, int sy, int tx, int ty) {
         while (tx > 0 && ty > 0){//因为sx, sy, tx, ty 是范围在 [1, 10^9] 的整数,逆推不能出界
            if (sx == tx && sy == ty){//判断是否到达了起始值
                return true;
            }
            //每次逆推只能有tx、ty中较大值减去较小值
            if (tx > ty){//此时只能有tx减去ty
                tx -= ty;
            }
            else{//此时只能有ty减去tx
                ty -= tx;
            }
        }
        return false;
    }

妙蛙。
然后:
结果超时,我。。。。。。这。。。

再优化思路:当反向推的时候,路径是唯一的。

回顾一下gcd的算法:辗转相除法与更相减损术。贴一个链接:https://blog.csdn.net/THISISPAN/article/details/7458234

所以:

更相减损法到辗转相除法的进化。如果遇到一个数很大,另一个数比较小的情况,可能要进行很多次减法才能达到一次除法的效果,从而使得算法的时间复杂度退化为O(N),其中N是原先的两个数中较大的一个

class Solution {
    public boolean reachingPoints(int sx, int sy, int tx, int ty) {
        //变相gcd
        if (tx < sx || ty < sy) return false;
        if (tx > ty) {
            //此时tx不可能==sx,如果sy==ty,就判断tx是不是有可能转成sx
            if (sy == ty)    
                return sx >= (tx % ty) && (tx - sx) % sy == 0;
            return reachingPoints(sx, sy, tx % ty, ty);
        }else if (tx < ty){
            if (sx == tx)    
                return sy >= (ty % tx) && (ty - sy) % sx == 0;
            return reachingPoints(sx, sy, tx, ty % tx);
        }else return tx == sx && ty == sy;
        }
}

贴一个gcd

public int gcd(int a,int b){
    int big = a>b?a:b;
    int small = a<b?a:b;
    if(big%small==0){
        return small;
    }
    return gcd(small,big%small);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值