Solution For Longest Path With Different Adjacent Characters
Problem Statement:
Given a matrix of lower alphabets and a dictionary. Find the longest path in the matrix such that all the characters in the path are different and the path is a valid word in the dictionary. The path can only be created using adjacent cells in 4 directions (Up, Down, Left, Right).
Solution:
The problem is solvable using a simple DFS algorithm. We traverse the matrix, for every cell in the matrix, we start a DFS traversal in all the 4 directions. We maintain a set to keep track of the characters we have already encountered. If a character is already in the set, we discard that traversal branch because we want all the characters to be different on the path. We also check if the constructed path is a valid word in the dictionary. If the path is a valid word and is longer than the current max-length path, we update the max-length path.
Algorithm:
1) Create a visited set to keep track of the visited nodes.
2) Initialize the max-length path to 0
3) Traverse the matrix, for every cell in the matrix.
4) Start a DFS traversal in all 4 directions. To avoid visiting the same node multiple times, we add the cell to the visited set before starting the DFS traversal.
5) Before traversing to a neighbor, we add the character on the current cell to a set used_chars
6) If a character is already in used_chars, we discard that traversal branch.
7) If the constructed path is a valid word in the dictionary, we update the max-length path.
8) After traversing all neighbors, we remove the character from used_chars set.
9) Remove the current cell from the visited set.
Code:
Here’s the implementation of the above algorithm:
“`
def dfs(matrix, row, col, visited, used_chars, dictionary, max_len):
visited.add((row, col)) # mark the current cell as visited
used_chars.add(matrix[row][col]) # add the current character to used_chars set
path = “”.join(used_chars) # construct the path
if len(path) > max_len and path in dictionary: # check if path is a valid word and is longer than the current max-length path
max_len = len(path)
for dr, dc in [(0, 1), (1, 0), (-1, 0), (0, -1)]: # traverse all 4 neighbors
r, c = row + dr, col + dc
if r >= 0 and r < len(matrix) and c >= 0 and c < len(matrix[0]) and (r, c) not in visited:
# traverse only if the cell is within the boundaries of the matrix, not already visited
# and not equal to the character already present in used_chars set
if matrix[r][c] not in used_chars:
max_len = dfs(matrix, r, c, visited, used_chars, dictionary, max_len)
used_chars.remove(matrix[row][col]) # remove the current character from used_chars set
visited.remove((row, col)) # remove the current cell from visited set
return max_len
def longestPath(matrix, dictionary):
# traverse the matrix, for every cell in the matrix.
max_len = 0
visited = set()
for i in range(len(matrix)):
for j in range(len(matrix[0])):
used_chars = set()
# start a DFS traversal in all 4 directions.
#To avoid visiting the same node multiple times,
# we add the cell to the visited set before starting the DFS traversal.
if (i, j) not in visited:
max_len = dfs(matrix, i, j, visited, used_chars, dictionary, max_len)
return max_len
“`
Time Complexity:
The time complexity of the above solution is O(4^(n*m)) where n and m are the dimensions of the matrix. In the worst case, all possible paths with all different characters will be checked.
Space Complexity:
The space complexity of the above solution is O(n*m) for the visited set and used_chars set. In the worst case, all cells are visited.
Step by Step Implementation For Longest Path With Different Adjacent Characters
We can use a DFS approach to find the longest path with different adjacent characters. We can keep track of the current path length and the previous character in a DFS helper function. If the current character is different from the previous character, we can update the path length. Otherwise, we reset the path length to 1. We can also update the global maximum path length as we explore the graph. public int longestPath(String s) { int maxLen = 0; for (int i = 0; i < s.length(); i++) { maxLen = Math.max(maxLen, dfs(s, i, 1, s.charAt(i))); } return maxLen; } private int dfs(String s, int i, int curLen, char prev) { if (i == s.length()) return curLen; if (s.charAt(i) != prev) { return dfs(s, i+1, curLen+1, s.charAt(i)); } else { return dfs(s, i+1, 1, s.charAt(i)); } }
def longest_path_with_different_adjacent_characters(s): # your code here
var longestPath = function(str) { // create a map to store the longest path for each letter // key is the letter, value is the longest path const map = {}; // create a visited map to store whether a letter has been visited // key is the letter, value is a boolean const visited = {}; // create a helper function to find the longest path for a given letter const longestPathForLetter = (letter) => { // base case: if the letter has been visited, return the longest path from the map if (visited[letter]) return map[letter]; // set the letter to visited visited[letter] = true; // get all the adjacent letters const adjLetters = getAdjacentLetters(letter); // for each adjacent letter, find the longest path let longest = 0; for (let i = 0; i < adjLetters.length; i++) { const adjLetter = adjLetters[i]; const path = longestPathForLetter(adjLetter); // update the longest path if necessary longest = Math.max(longest, path); } // increment the longest path by 1 (for the current letter) longest++; // store the longest path in the map map[letter] = longest; // return the longest path return longest; }; // create a helper function to get all adjacent letters const getAdjacentLetters = (letter) => { const letters = []; // iterate through the string for (let i = 0; i < str.length; i++) { // if the current letter is equal to the given letter and the next letter is not equal to the given letter if (str[i] === letter && str[i + 1] !== letter) { // push the next letter into the array letters.push(str[i + 1]); } } return letters; }; // iterate through the string let longest = 0; for (let i = 0; i < str.length; i++) { // find the longest path for the current letter const path = longestPathForLetter(str[i]); // update the longest path if necessary longest = Math.max(longest, path); } // return the longest path return longest; };
class Solution { public: int longestPathWithDifferentAdjacentCharacters(string s) { int n = s.length(); int ans = 0; vector> dp(n, vector (26, 0)); for (int i = 0; i < n; ++i) { int c = s[i] - 'a'; dp[i][c] = 1; for (int j = 0; j < i; ++j) { int prev = s[j] - 'a'; if (dp[j][c] == 0 && prev != c) { dp[i][c] = dp[j][prev] + 1; } } ans = max(ans, dp[i][c]); } return ans; } };
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace ConsoleApplication1 { class Program { static void Main(string[] args) { string s = "abcabcbb"; int result = LongestSubstring(s); Console.WriteLine("result: " + result); Console.ReadLine(); } public static int LongestSubstring(string s) { if (s == null || s.Length == 0) { return 0; } HashSetset = new HashSet (); int max = 0; int j = 0; for (int i = 0; i < s.Length; i++) { while (j < s.Length) { if (!set.Contains(s[j])) { set.Add(s[j]); j++; max = Math.Max(max, set.Count); } else { set.Remove(s[i]); i++; break; } } } return max; } } }