C++LeetCode 구현(187.중복 되 는 DNA 서열 구하 기)
6071 단어 C++중복 되 는 DNA 서열 구하 기LeetCode
All DNA is composed of a series of nucleotides abbreviated as A, C, G, and T, for example: "ACGAATTCCG". When studying DNA, it is sometimes useful to identify repeated sequences within the DNA.
Write a function to find all the 10-letter-long sequences (substrings) that occur more than once in a DNA molecule.
Example:
Input: s = "AAAAACCCCCAAAAACCCCCCAAAAAGGGTTT"
Output: ["AAAAACCCCC", "CCCCCAAAAA"]
이 문 제 를 보고 CS 의 중요 한 가지 생물 정보 인 Bioinformatics 연구 내용 에 속 해 야 한다 고 생각 했 습 니 다.DNA 서열 특징 을 연구 하 는 중요 한 의 미 는 물론 이 고 우리 많은 코드 농업 에 있어 알고리즘 에 전념 하 세 요.이 문 제 는 비트 조작 Bit Manipulation 으로 풀 겠 습 니 다.컴퓨터 는 바 이 너 리 저장 의 특징 으로 인해 몇 가지 문 제 를 교묘 하 게 해결 할 수 있다. Single Number 화해시키다 Single Number II 모두 교묘 하 게 비트 조작 을 이용 하여 해답 을 구한다.이 문 제 는 입력 문자열 을 구성 하 는 문자 가 4 가지 밖 에 없 기 때문에 각각 A,C,G,T 입 니 다.다음은 ASCII 코드 를 바 이 너 리 로 표시 합 니 다.
A: 0100 0001 C: 0100 0011 G: 0100 0111 T: 0101 0100
위 치 를 이용 하여 문 자 를 구분 하 는 것 이 목적 이기 때문에 당연히 적 을 수록 좋다.관찰 을 통 해 모든 문자 의 뒷 세 자리 가 다 르 기 때문에 마지막 세 자리 로 이 네 문 자 를 구분 할 수 있다.문 제 는 10 글자 길이 의 문자열 로 각 문 자 를 세 자리 로 구분 하고 10 자 는 30 자리 가 필요 하 며 32 비트 컴퓨터 에서 도 OK.후 30 위 를 추출 하기 위해 서 는 마스크 를 사용 해 야 합 니 다.추출 값 은 0x7ffff 입 니 다.이 마스크 를 사용 하면 후 27 위 를 추출 하고 왼쪽으로 세 자 리 를 옮 기 면 됩 니 다.알고리즘 은 열 번 째 문 자 를 꺼 낼 때 HashMap 에 존재 합 니 다.이 문자열 과 주파수 맵 이 나타 난 다음 에 왼쪽으로 세 자 를 옮 길 때마다 문 자 를 바 꾸 고 새 문자열 이 HashMap 에 나타 난 횟수 를 찾 습 니 다.만약 에 전에 한 번 나타 난 적 이 있다 면 현재 문자열 을 반환 값 의 배열 에 저장 하고 나타 난 횟수 를 하나 더 합 니 다.나타 나 지 않 았 다 면,1 에 투사 합 니 다.전체 과정 을 더욱 명확 하 게 논술 하기 위해 제목 에서 준 예 로 전체 과정 을 분석한다.
먼저 앞의 9 개의 문 자 를 꺼 내 서 위의 분석 에 따 르 면 세 자리 로 한 문 자 를 표시 할 수 있 기 때문에 이 9 개의 문 자 는 이 진 으로 0010010010010011011011011011 을 표시 한 다음 에 문자열 을 계속 옮 겨 다 닐 수 있 습 니 다.다음 에 들 어 오 는 문 자 는 C 입 니 다.현재 문 자 는 AAAAACCCCC 이 고 이 진 은 0010010010011011011011011011 을 표시 한 다음 에 HashMap 에 저장 합 니 다.바 이 너 리 의 장점 은 하나의 int 변수 로 임의의 10 개의 문자 배열 을 표시 할 수 있다 는 것 입 니 다.문자열 을 직접 저장 하 는 것 보다 메모리 공간 을 크게 절약 한 다음 에 다음 문자 C 를 읽 을 수 있 습 니 다.이때 문자열 은 AAAACCCCCA 입 니까?아니면 바 이 너 리 의 표현 형식 입 니까?이런 식 으로 유추 하면 특정한 서열 이 나타 나 기 전에 결과 res 에 저장 하면 됩 니 다.참조 코드 는 다음 과 같 습 니 다.
해법 1:
class Solution {
public:
vector<string> findRepeatedDnaSequences(string s) {
vector<string> res;
if (s.size() <= 10) return res;
int mask = 0x7ffffff, cur = 0;
unordered_map<int, int> m;
for (int i = 0; i < 9; ++i) {
cur = (cur << 3) | (s[i] & 7);
}
for (int i = 9; i < s.size(); ++i) {
cur = ((cur & mask) << 3) | (s[i] & 7);
if (m.count(cur)) {
if (m[cur] == 1) res.push_back(s.substr(i - 9, 10));
++m[cur];
} else {
m[cur] = 1;
}
}
return res;
}
};
위의 방법 은 좀 더 간결 하 게 쓸 수 있 습 니 다.여 기 는 HashMap 을 HashSet 로 대체 할 수 있 습 니 다.현재 의 숫자 가 HashSet 에 존재 하 는 한 res 에 넣 습 니 다.여기 res 도 HashSet 로 정의 하면 HashSet 의 중복 항목 이 없 는 특징 을 이용 하여 정확 한 답 을 얻 을 수 있 습 니 다.마지막 으로 HashSet 을 vector 로 바 꾸 면 됩 니 다.참조 코드 는 다음 과 같 습 니 다.해법 2:
class Solution {
public:
vector<string> findRepeatedDnaSequences(string s) {
unordered_set<string> res;
unordered_set<int> st;
int cur = 0;
for (int i = 0; i < 9; ++i) cur = cur << 3 | (s[i] & 7);
for (int i = 9; i < s.size(); ++i) {
cur = ((cur & 0x7ffffff) << 3) | (s[i] & 7);
if (st.count(cur)) res.insert(s.substr(i - 9, 10));
else st.insert(cur);
}
return vector<string>(res.begin(), res.end());
}
};
위의 방법 은 모두 세 자리 로 한 문 자 를 표시 합 니 다.여 기 는 두 자리 로 한 문 자 를 표시 할 수 있 습 니 다.00 은 A,01 은 C,10 은 G,11 은 T 를 표시 합 니 다.그러면 모두 20 자리 가 필요 하면 10 글자 흐름 을 표시 할 수 있 습 니 다.나머지 사 고 는 위의 방법 과 똑 같 습 니 다.여기 있 는 mask 는 18 자리 만 표시 하기 때문에 0x3ffff 가 되 었 습 니 다.참조 코드 는 다음 과 같 습 니 다.해법 3:
class Solution {
public:
vector<string> findRepeatedDnaSequences(string s) {
unordered_set<string> res;
unordered_set<int> st;
unordered_map<int, int> m{{'A', 0}, {'C', 1}, {'G', 2}, {'T', 3}};
int cur = 0;
for (int i = 0; i < 9; ++i) cur = cur << 2 | m[s[i]];
for (int i = 9; i < s.size(); ++i) {
cur = ((cur & 0x3ffff) << 2) | (m[s[i]]);
if (st.count(cur)) res.insert(s.substr(i - 9, 10));
else st.insert(cur);
}
return vector<string>(res.begin(), res.end());
}
};
메모리 공간 을 절약 하 는 것 을 고려 할 필요 가 없다 면 10 개의 문자 로 구 성 된 문자열 을 HashSet 에 직접 저장 할 수 있 습 니 다.그러면 mask 같은 것 도 필요 하지 않 지만 생각 은 위의 방법 과 같 습 니 다.해법 4:
class Solution {
public:
vector<string> findRepeatedDnaSequences(string s) {
unordered_set<string> res, st;
for (int i = 0; i + 9 < s.size(); ++i) {
string t = s.substr(i, 10);
if (st.count(t)) res.insert(t);
else st.insert(t);
}
return vector<string>{res.begin(), res.end()};
}
};
C++구현 LeetCode(187.중복 되 는 DNA 서열)에 관 한 이 글 은 여기까지 소개 되 었 습 니 다.더 많은 관련 C++구현 중복 되 는 DNA 서열 내용 은 우리 의 이전 글 을 검색 하거나 아래 의 관련 글 을 계속 조회 하 시기 바 랍 니 다.앞으로 많은 응원 부 탁 드 리 겠 습 니 다!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Visual Studio에서 파일 폴더 구분 (포함 경로 설정)Visual Studio에서 c, cpp, h, hpp 파일을 폴더로 나누고 싶었습니까? 어쩌면 대부분의 사람들이 있다고 생각합니다. 처음에 파일이 만들어지는 장소는 프로젝트 파일 등과 같은 장소에 있기 때문에 파일...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.