Find the Longest Substring in Alphabetical Order

Find the longest substring in alphabetical order

Try changing this:

        if len(set(substr)) != (end - start): # found duplicates or EOS
break
if (ord(max(sorted(substr))) - ord(min(sorted(substr))) + 1) == len(substr):

to this:

        if len(substr) != (end - start): # found duplicates or EOS
break
if sorted(substr) == list(substr):

That will display ccl for your example input string. The code is simpler because you're trying to solve a simpler problem :-)

Finding Longest substring in alphabetical order (Need Advice for Logic)

Instead of adding s[x] to temp, add s[x+1].

Initialize both temp and longest to the first character, so that the code will work with a 1-character string or a string that has no sequence in alphabetical order.

Stop the iteration one character before the end so s[x+1] doesn't give you an IndexError.

When the next character is out of order, reinitialize temp to the next character.

You can eliminate the variable "word".

s = 'azcbobobegghakl'
longest = s[0]
temp = s[0]
for x in range(len(s)-1):
if (s[x] <= s[x+1]):
temp += s[x+1]
if len(temp) > len(longest):
longest = temp
else:
temp = s[x+1]
print('Longest substring in alphabetical order is: ' + longest)

Finding longest substring in alphabetical order

There are many things to improve in your code but making minimum changes so as to make it work. The problem is you should have if last_pos(i) != None: in your for loop (i instead of i+1) and you should compare diff (not diff - 1) against maxLen. Please read other answers to learn how to do it better.

for i in range(len(s)):
if last_pos(i) != None:
diff = last_pos(i) - i + 1
if diff > maxLen:
maxLen = diff
startPos = i
endPos = startPos + diff - 1

Longest alphabetical substring - where to begin

If you are struggling with the concepts and logic behind solving this problem, I would recommend perhaps stepping back a little and going through easier coding tutorials and interactive exercises. You might also enjoy experimenting with JavaScript, where it might be easier to get creative right from the outset, building out snippets and/or webpages that one can immediately interact with in the browser. Then when you get more fun coding vocabulary under your belt, the algorithmic part of it will seem more familiar and natural. I also think letting your own creativity and imagination guide you can be a very powerful learning process.

Let's forget about the alphabetical part for the moment. Imagine we have a bag of letters that we pull out one at a time without knowing which is next and we have to record the longest run of Rs in a row. How would you do it? Let's try to describe the process in words, then pseudocode.

We'll keep a container for the longest run we've seen so far and another to check the current run. We pull letters until we hit two Rs in a row, which we put it in the "current" container. The next letter is not an R, which means our run ended. The "longest-so-far" run is empty so we pour the "current" container in it and continue. The next four letters are not Rs so we just ignore them. Then we get one R, which we put in "current" and then an H. Our run ended again but this time our one R in "current" was less than the two we already have in "longest-so-far" so we keep those and empty "current."

We get an A, a B, and a C, and then a run of five Rs, which we put into the "current" container one by one. Our bag now contains the last letter, a T. We see that our run ended again and that "current" container has more than the "longest-so-far" container so we pour out "longest" and replace its contents with the five Rs in "current." That's it, we found the longest run of Rs in the bag. (If we had more runs, each time one ended we'd choose whether to replace the contents of "longest-so-far.")

In pseudocode:

// Initialise
current <- nothing
longest <- nothing

for letter in bag:
if letter == 'R':
add 'R' to current
else:
if there are more letters
in current than longest:
empty longest and pour
in letters from current
otherwise:
empty current to get ready
for the next possible run

Now the alphabetical stipulation just slightly complicates our condition. We will need to keep track of the most recent letter placed in "current," and in order for a run to continue, its not seeing another of the same letter that counts. Rather, the next letter has to be "greater" (lexicographically) than the last one we placed in current; otherwise the run ends and we perform our quantity check against "longest-so-far."

Finding longest alphabetical substring - understanding the concepts in Python

Let's go through your code step by step.

First we assume that the first character forms the longest sequence. What we will do is try improving this guess.

s = 'cyqfjhcclkbxpbojgkar'

lstring = s[0]
slen = 1

The first loop then picks some index i, it will be the start of a sequence. From there, we will check all existing sequences starting from i by looping over the possible end of a sequence with the nested loop.

for i in range(len(s)): # This loops over the whole string indices
for j in range(i,len(s)-1): # This loops over indices following i

This nested loops will allow us to check every subsequence by picking every combination of i and j.

The first if statement intends to check if that sequence is still an increasing one. If it is not we break the inner loop as we are not interested in that sequence.

if s[j+1] >= s[j]:
...
else:
break

We finally need to check if the current sequence we are looking at is better than our current guess by comparing its length to slen, which is our best guess.

if (j+1)-i+1 > slen:
lstring = s[i:(j+1)+1]
slen = (j+1)-i+1

Improvements

Note that this code is not optimal as it needlessly traverses your string multiple times. You could implement a more efficient approach that traverses the string only once to recover all increasing substrings and then uses max to pick the longuest one.

s = 'cyqfjhcclkbxpbojgkar'

substrings = []

start = 0
end = 1
while end < len(s):
if s[end - 1] > s[end]:
substrings.append(s[start:end])
start = end + 1
end = start + 1
else:
end += 1

lstring = max(substrings, key=len)

print("Longest substring in alphabetical order is: " + lstring)

The list substrings looks like this after the while-loop: ['cy', 'fj', 'ccl', 'bx', 'bo', 'gk']

From these, max(..., key=len) picks the longuest one.

Find the longest substring in alphabetical order. What is wrong with my code

You aren't taking the current character into account if you find the next character isn't in alphabetical order, and that's why you're missing one character in the end.

Instead, you should always process the current character first before resetting temp if the next character isn't in order.

s = 'azcbobobegghakl'
i = 0

temp = '' #temporary variable I use to change longest
longest = ''
for i in range(len(s)-1):
temp += s[i]
if len(longest) < len(temp):
longest = temp
if s[i] > s[i+1]: #checks if it's in alphabetical order
temp = '' #reset temp after every substring
if len(longest) < len(temp):
longest += temp #update longest if the new substring is longer
i +=1



print('Longest substring in alphabetical order is:', longest)

This outputs:

Longest substring in alphabetical order is: beggh

Longest substring in alphabetical order Javascript

The algorithm can be linear, I think you are overcomplicating it placing loops inside loops.

I would use something like