Skip to content

Commit 0b40450

Browse files
committed
leetcode
1 parent fe0148d commit 0b40450

File tree

7 files changed

+336
-0
lines changed

7 files changed

+336
-0
lines changed
Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
/*
2+
3+
4+
-* Minimum Genetic Mutation *-
5+
6+
7+
A gene string can be represented by an 8-character long string, with choices from 'A', 'C', 'G', and 'T'.
8+
9+
Suppose we need to investigate a mutation from a gene string start to a gene string end where one mutation is defined as one single character changed in the gene string.
10+
11+
For example, "AACCGGTT" --> "AACCGGTA" is one mutation.
12+
There is also a gene bank bank that records all the valid gene mutations. A gene must be in bank to make it a valid gene string.
13+
14+
Given the two gene strings start and end and the gene bank bank, return the minimum number of mutations needed to mutate from start to end. If there is no such a mutation, return -1.
15+
16+
Note that the starting point is assumed to be valid, so it might not be included in the bank.
17+
18+
19+
20+
Example 1:
21+
22+
Input: start = "AACCGGTT", end = "AACCGGTA", bank = ["AACCGGTA"]
23+
Output: 1
24+
Example 2:
25+
26+
Input: start = "AACCGGTT", end = "AAACGGTA", bank = ["AACCGGTA","AACCGCTA","AAACGGTA"]
27+
Output: 2
28+
Example 3:
29+
30+
Input: start = "AAAAACCC", end = "AACCCCCC", bank = ["AAAACCCC","AAACCCCC","AACCCCCC"]
31+
Output: 3
32+
33+
34+
Constraints:
35+
36+
start.length == 8
37+
end.length == 8
38+
0 <= bank.length <= 10
39+
bank[i].length == 8
40+
start, end, and bank[i] consist of only the characters ['A', 'C', 'G', 'T'].
41+
42+
43+
44+
45+
*/
46+
47+
import 'dart:collection';
48+
import 'dart:math';
49+
50+
// Breadth first Search
51+
class A {
52+
// Runtime: 375 ms, faster than 100.00% of Dart online submissions for Minimum Genetic Mutation.
53+
// Memory Usage: 142.8 MB, less than 100.00% of Dart online submissions for Minimum Genetic Mutation.
54+
bool isValid(String s, String target) {
55+
int changedCount = 0;
56+
for (int i = 0; i < s.length; i++) {
57+
if (s[i] != target[i]) changedCount++;
58+
}
59+
if (changedCount == 1)
60+
return true; //if ony one char is changed then "MUTATION IS VALID"
61+
return false; //changedCount == 0 or changedCount > 1 => "MUTATION IS INVALID"
62+
}
63+
64+
int minMutation(String start, String end, List<String> bank) {
65+
bank.add(start); //start is also a valid string mutation
66+
int n = bank.length;
67+
68+
Queue<String> q = Queue();
69+
//to keep a track of visited strings from bank
70+
List<bool> visited = List.filled(n, false);
71+
visited[n - 1] = true; //marking index of "start" string as visited
72+
q.add(start);
73+
74+
int stepCount = 0;
75+
while (q.isNotEmpty) {
76+
int size = q.length;
77+
//iterating level wise to keep a track of steps(levels of bfs)
78+
while (size-- != 0) {
79+
String curr = q.first;
80+
q.removeFirst();
81+
if (curr == end) return stepCount; //target found
82+
for (int i = 0; i < n; i++) {
83+
bool valid = isValid(curr, bank[i]);
84+
if (!valid || visited[i]) continue;
85+
86+
visited[i] = true;
87+
q.add(bank[i]);
88+
}
89+
}
90+
stepCount++; //after each level stepCount is increased by 1
91+
}
92+
return -1;
93+
}
94+
}
95+
96+
// DFS
97+
class B {
98+
// Runtime: 402 ms, faster than 100.00% of Dart online submissions for Minimum Genetic Mutation.
99+
// Memory Usage: 140.4 MB, less than 100.00% of Dart online submissions for Minimum Genetic Mutation.
100+
bool isOneAway(String start, String end) {
101+
int count = 0;
102+
for (int i = 0; i < start.length && count < 2; i++) {
103+
if (start.codeUnitAt(i) != end.codeUnitAt(i)) {
104+
count++;
105+
}
106+
}
107+
return count == 1;
108+
}
109+
110+
int backtrack(String start, String end, int count, List<String> bank,
111+
List<bool> visited) {
112+
if (start == end) {
113+
return 0;
114+
}
115+
int ans = double.maxFinite.toInt();
116+
for (int i = 0; i < bank.length; i++) {
117+
if (!visited[i] && isOneAway(start, bank[i])) {
118+
visited[i] = true;
119+
ans = min(ans, backtrack(bank[i], end, count + 1, bank, visited));
120+
visited[i] = false;
121+
}
122+
}
123+
if (ans == double.maxFinite.toInt()) {
124+
return ans;
125+
}
126+
return ans + 1;
127+
}
128+
129+
int minMutation(String start, String end, List<String> bank) {
130+
List<bool> visited = List.filled(bank.length, false);
131+
int ans = backtrack(start, end, 0, bank, visited);
132+
return ans == double.maxFinite.toInt() ? -1 : ans;
133+
}
134+
}
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
package main
2+
3+
func minMutation(start string, end string, bank []string) int {
4+
5+
if start == end {
6+
return 0
7+
}
8+
9+
charSet := []rune{'A', 'C', 'G', 'T'}
10+
//convert bank array to map
11+
bankmap := make(map[string]struct{})
12+
for _, seq := range bank {
13+
bankmap[seq] = struct{}{}
14+
}
15+
16+
level := 0
17+
//visited map that stores all sequences visited
18+
visited := make(map[string]struct{})
19+
20+
//return all possible "valid" mutations
21+
getNextMutation := func(mut string, pos int) []string {
22+
mutations := []string{}
23+
for _, char := range charSet {
24+
//generate a new seqence by replacing the character at "pos" with each character in charSet
25+
newseq := mut[:pos] + string(char) + mut[pos+1:]
26+
//check if the new sequence exist in bank, and has not been visited already
27+
if isInMap(newseq, bankmap) && !isInMap(newseq, visited) {
28+
mutations = append(mutations, newseq)
29+
visited[newseq] = struct{}{} //update visited map
30+
}
31+
}
32+
return mutations
33+
}
34+
35+
//bfs queue
36+
queue := []string{}
37+
queue = append(queue, start)
38+
visited[start] = struct{}{}
39+
for len(queue) > 0 {
40+
qlen := len(queue)
41+
for _, seq := range queue[:qlen] {
42+
43+
if seq == end {
44+
return level
45+
}
46+
//get all possible mutations by modifying each character of the sequence
47+
for idx := range seq {
48+
mutations := getNextMutation(seq, idx)
49+
queue = append(queue, mutations...)
50+
}
51+
}
52+
level++
53+
queue = queue[qlen:]
54+
}
55+
return -1
56+
}
57+
58+
func isInMap(seq string, m map[string]struct{}) bool {
59+
_, ok := m[seq]
60+
return ok
61+
}
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
# 🔥 BFS/DFS 🔥 || 2 Approaches || Simple Fast and Easy || with Explanation
2+
3+
## Solution - 1 Breadth First Search
4+
5+
```dart
6+
import 'dart:collection';
7+
8+
class Solution {
9+
// Runtime: 375 ms, faster than 100.00% of Dart online submissions for Minimum Genetic Mutation.
10+
// Memory Usage: 142.8 MB, less than 100.00% of Dart online submissions for Minimum Genetic Mutation.
11+
bool isValid(String s, String target) {
12+
int changedCount = 0;
13+
for (int i = 0; i < s.length; i++) {
14+
if (s[i] != target[i]) changedCount++;
15+
}
16+
if (changedCount == 1)
17+
return true; //if ony one char is changed then "MUTATION IS VALID"
18+
return false; //changedCount == 0 or changedCount > 1 => "MUTATION IS INVALID"
19+
}
20+
21+
int minMutation(String start, String end, List<String> bank) {
22+
bank.add(start); //start is also a valid string mutation
23+
int n = bank.length;
24+
25+
Queue<String> q = Queue();
26+
//to keep a track of visited strings from bank
27+
List<bool> visited = List.filled(n, false);
28+
visited[n - 1] = true; //marking index of "start" string as visited
29+
q.add(start);
30+
31+
int stepCount = 0;
32+
while (q.isNotEmpty) {
33+
int size = q.length;
34+
//iterating level wise to keep a track of steps(levels of bfs)
35+
while (size-- != 0) {
36+
String curr = q.first;
37+
q.removeFirst();
38+
if (curr == end) return stepCount; //target found
39+
for (int i = 0; i < n; i++) {
40+
bool valid = isValid(curr, bank[i]);
41+
if (!valid || visited[i]) continue;
42+
43+
visited[i] = true;
44+
q.add(bank[i]);
45+
}
46+
}
47+
stepCount++; //after each level stepCount is increased by 1
48+
}
49+
return -1;
50+
}
51+
}
52+
```
53+
54+
## Solution - 2 Depth First Search
55+
56+
```dart
57+
class Solution {
58+
// Runtime: 402 ms, faster than 100.00% of Dart online submissions for Minimum Genetic Mutation.
59+
// Memory Usage: 140.4 MB, less than 100.00% of Dart online submissions for Minimum Genetic Mutation.
60+
bool isOneAway(String start, String end) {
61+
int count = 0;
62+
for (int i = 0; i < start.length && count < 2; i++) {
63+
if (start.codeUnitAt(i) != end.codeUnitAt(i)) {
64+
count++;
65+
}
66+
}
67+
return count == 1;
68+
}
69+
70+
int backtrack(String start, String end, int count, List<String> bank,
71+
List<bool> visited) {
72+
if (start == end) {
73+
return 0;
74+
}
75+
int ans = double.maxFinite.toInt();
76+
for (int i = 0; i < bank.length; i++) {
77+
if (!visited[i] && isOneAway(start, bank[i])) {
78+
visited[i] = true;
79+
ans = min(ans, backtrack(bank[i], end, count + 1, bank, visited));
80+
visited[i] = false;
81+
}
82+
}
83+
if (ans == double.maxFinite.toInt()) {
84+
return ans;
85+
}
86+
return ans + 1;
87+
}
88+
89+
int minMutation(String start, String end, List<String> bank) {
90+
List<bool> visited = List.filled(bank.length, false);
91+
int ans = backtrack(start, end, 0, bank, visited);
92+
return ans == double.maxFinite.toInt() ? -1 : ans;
93+
}
94+
}
95+
```

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,8 @@ This repo contain leetcode solution using DART and GO programming language. Most
120120
- [Where Will the Ball Fall](WhereWillTheBallFall/where_will_the_ball_fall.dart)
121121
- [Word Pattern](WordPattern/word_pattern.dart)
122122
- [Nim Game](NimGame/nim_game.dart)
123+
- [Range Sum Query - Immutable](RangeSumQuery-Immutable/range_sum_query_immutable.dart)
124+
- [Minimum Genetic Mutation](MinimumGeneticMutation/minimum_genetic_mutation.dart)
123125

124126
## Reach me via
125127

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/*
2+
3+
4+
5+
-* Range Sum Query - Immutable *-
6+
7+
8+
9+
10+
Given an integer array nums, handle multiple queries of the following type:
11+
12+
Calculate the sum of the elements of nums between indices left and right inclusive where left <= right.
13+
Implement the NumArray class:
14+
15+
NumArray(int[] nums) Initializes the object with the integer array nums.
16+
int sumRange(int left, int right) Returns the sum of the elements of nums between indices left and right inclusive (i.e. nums[left] + nums[left + 1] + ... + nums[right]).
17+
18+
19+
Example 1:
20+
21+
Input
22+
["NumArray", "sumRange", "sumRange", "sumRange"]
23+
[[[-2, 0, 3, -5, 2, -1]], [0, 2], [2, 5], [0, 5]]
24+
Output
25+
[null, 1, -1, -3]
26+
27+
Explanation
28+
NumArray numArray = new NumArray([-2, 0, 3, -5, 2, -1]);
29+
numArray.sumRange(0, 2); // return (-2) + 0 + 3 = 1
30+
numArray.sumRange(2, 5); // return 3 + (-5) + 2 + (-1) = -1
31+
numArray.sumRange(0, 5); // return (-2) + 0 + 3 + (-5) + 2 + (-1) = -3
32+
33+
34+
Constraints:
35+
36+
1 <= nums.length <= 104
37+
-105 <= nums[i] <= 105
38+
0 <= left <= right < nums.length
39+
At most 104 calls will be made to sumRange.
40+
41+
42+
43+
*/
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
package main

RangeSumQuery-Immutable/range_sum_query_immutable.md

Whitespace-only changes.

0 commit comments

Comments
 (0)