可以替换的最小子字符串使字符串具有相同数量的每个字符

时间:2016-08-10 15:28:25

标签: c# string algorithm time-complexity dynamic-programming

我正试图解决几乎就是这个问题。特别是我给了一个字符串ss.Length % 4 == 0和每个s[i]'A''C''T'或{{}之一1}}。我想找到我可以替换的最小子字符串,以便'G''A''C''T'中的每一个都出现'G'次。

例如,对于s.Length / 4,一个最佳解决方案是将子字符串s="GAAATAAA"替换为"AAATA",从而产生"TTCCG"

我在下面的评论中描述了我的方法,我想知道它是否真的正确,因为它会让我得到正确答案。

"GTTCCGAA"

4 个答案:

答案 0 :(得分:0)

如果字符串已经有一组平衡的字符,那么你就完成了,不需要做任何事情。

否则,您总是可以通过替换最小的零字符来解决问题。你可以通过添加缺少的任何字符来实现。例如,考虑你的测试用例:

GAAATAAA

出现次数最多的角色是A和6.你还需要5个额外的G,5个额外的T和6个额外的C&#39。因此,用包含A本身的所需字符替换一个A:

GAAATAA [AGGGGGTTTTTCCCCCC]

由于原始A被替换为A,因此您实际上已经替换了零字符,这是可能的最小值。

答案 1 :(得分:0)

我认为您的解决方案可行,但其复杂性太高了。
这是另一种解决方案 如果字符串中的字符数字返回{'A',4},{'C',6},{'G',6},{'T',4}必须以C或G开头的子字符串,则结束使用C或G并且长度> = 2
所以我们需要做的是拿每个验证这些条件的字符串,测试它是否包含“坏字符”在我们的情况下一个C和一个G.如果它的长度= 2我们赢了,否则我们保存在一个临时变量中继续我们的测试

<div style="background-color:#FFD382;" align="left" class="multiline">
         Peter 
         How are you 
         2016-8-10
</div>

我做了一些修改来处理边界情况。 这是一些测试样本,结果我看起来很好 enter image description here

答案 2 :(得分:0)

思考?对不起凌乱的代码+ python解决方案。我最初开始在手机上写这个,感觉很懒。

import re
from itertools import permutations

def find_min(s):
    freq = {ch:0 for ch in 'ATGC'}
    for ch in s:
        freq[ch] += 1
    desired_len = int(len(s)/4)
    fixes = {ch:desired_len-freq[ch] for ch in 'ATGC'}
    replacement = ''
    for ch in fixes:
        adj = fixes[ch]
        if adj < 0:
            replacement += ch*(-1*adj)
    perms = set(permutations(replacement))
    m = len(s)
    to_replace = ''
    for rep in perms:
        regex = '.*?'.join([ch for ch in rep])
        finds = re.findall(regex,s)
        if finds:
            x = sorted(finds, key=lambda x:len(x))[0]
            if m >= len(x):
                m = len(x)
                to_replace = x

    print_replacement(s, to_replace, fixes)

def print_replacement(inp, to_replace, fixes):
    replacement = ''
    for ch in to_replace:
        if fixes[ch] > 0:
            replacement += ch
    for ch in fixes:
        if fixes[ch] > 0:
            replacement += ch*fixes[ch]
    print('{0}\t\t- Replace {1} with {2} (min length: {3})'.format(inp ,to_replace, replacement, len(replacement)))


def main():
    inputs =  ["GAAATAAA", "CACCGCTACCGC", "CAGCTAGC", "AAAAAAAA", "GAAAAAAA", "GATGAATAACCA", "ACGT"]
    for inp in inputs:
        find_min(inp)

if __name__ == '__main__':
    main()

感谢@AnotherGeek测试输入!这是输出。

GAAATAAA        - Replace AAATA with TCCGT (min length: 5)
CACCGCTACCGC    - Replace CACCGC with AGAGTT (min length: 6)
CAGCTAGC        - Replace C with T (min length: 1)
AAAAAAAA        - Replace AAAAAA with CCGGTT (min length: 6)
GAAAAAAA        - Replace AAAAA with CCGTT (min length: 5)
GATGAATAACCA    - Replace ATGAA with TGCGT (min length: 5)
ACGT            - Replace  with  (min length: 0)

我意识到这非常低效。有任何改进建议吗?

答案 3 :(得分:0)

public int balancedString(String s) {
        int[] count = new int[128];
        int n = s.length(), res = n, i = 0, k = n / 4;
        for (int j = 0; j < n; ++j) {
            ++count[s.charAt(j)];
        }
        for (int j = 0; j < n; ++j) {
            --count[s.charAt(j)];
            while (i < n && count['A'] <= k && count['C'] <= k && count['T'] <= k && count['G'] <= k) {
                res = Math.min(res, j - i + 1);
                ++count[s.charAt(i++)];
            }
        }
        return res;
    }