这道Google的面试题,难倒了97%的程序员…

Google的面试有多难?据相关数据,谷歌每年收到竞聘者简历近300万份,而录取率仅有0.2%。

正好,这两天有G家面试官提供了一道Google的面试题,据说通过率只有3%,就拿出来跟大家分享一下。

题目链接:基因相似度

LintCode 领扣

描述

给定两段基因片段 Gene1Gene2 ,基因片段中由数字和"ACGT"四种字符组成。
每一个字符前都会有相应的数字,这个数字是描述该字符连续出现的数量,例如:"1A2C2G1T" 表示 "ACCGGT"。
返回一个表示这两个基因片段的相似度的字符串,相似度字符串的定义是:"相同位置上的字符相同个数" + "/" + "总字符个数"。


  • Gene1 和 Gene2 仅仅包含数字和["A", "C", "G", "T"]这四种字母
  • Gene1 以及 Gene2 的长度范围是: [1, 100000]
  • 基因片段中字符数量的范围是: [1, 10000000]
  • 保证扩充之后的 Gene1 以及 Gene2 的长度相同


示例 1:

输入:
Gene1: "2T3G"
Gene2: "3T2G"
输出: 
"4/5"
解释: 
"TTTGG" 和 "TTGGG" 有 4 处位置上的基因片段相同,所以 "4/5"

示例2:

输入:
Gene1 = "3T2G4A1C"
Gene2 = "6T1A2C1G"
输出: 
"4/10"
解释:
"TTTGGAAAAC" 和 "TTTTTTACCG" 有 4 个位置具有相同的基因片段, 所以 "4/10"

解法:双指针

算法:双指针

解题思路

若直接将两个字符串解压拆开,然后从头开始比较会超时,所以我们可以将两个字符串当成两段大区间,每个大区间里面有很多个小区间。 每一个小区间主要有两个参数,长度以及字符种类。 利用双指针遍历这两段大区间,统计相同的字符数即可。

复杂度分析

时间复杂度:O(n)

需要遍历一遍字符串长度

空间复杂度:O(1)

不需要开辟新的空间。

源代码

class Gene{ 
    private int index; 
    public int count; 
    private char[] gene; 
    private char gene_base;  
     
    public Gene(){} 
    public Gene(String a){ 
        count = 0; 
        index = 0; 
        gene = a.toCharArray(); 
        gene_base = ' '; 
    } 
    public void updateGene(){ 
        count = 0; 
        gene_base = ' '; 
        if(index >= gene.length){ 
            return; 
        } 
 
        while(index < gene.length && gene_base == ' '){ 
            if(gene[index] >= '0' && gene[index] <= '9'){ 
                count = count * 10 + (gene[index] - '0'); 
            } 
 
            else{ 
                gene_base = gene[index]; 
            } 
            index ++; 
        } 
    } 
    public char get_base(){ 
        return gene_base; 
    } 
} 
 
 
public class Solution { 
    /** 
     * @param Gene1: a string 
     * @param Gene2: a string 
     * @return: return the similarity of two gene fragments 
     */ 
    public String GeneSimilarity(String Gene1, String Gene2) { 
        // write your code here 
        int same_time = 0, count_time = 0; 
 
        Gene g1 = new Gene(Gene1); 
        Gene g2 = new Gene(Gene2); 
 
        g1.updateGene(); 
        g2.updateGene(); 
 
        count_time += g1.count; 
        while(g1.get_base() != ' ' && g2.get_base() != ' '){ 
            if(g1.get_base() == g2.get_base()){ 
                same_time += Math.min(g1.count, g2.count); 
            } 
 
            if(g1.count > g2.count){ 
                g1.count -= g2.count; 
                g2.updateGene(); 
            } 
            else if(g1.count < g2.count){ 
                g2.count -= g1.count; 
                g1.updateGene(); 
                count_time += g1.count; 
            } 
            else{ 
                g1.updateGene(); 
                g2.updateGene(); 
                count_time += g1.count; 
            } 
        } 
        return String.valueOf(same_time) +  "/" + String.valueOf(count_time); 
    } 
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值