Implement an algorithm to determine if a string has all unique characters. What if you can not use additional data structure?

In order to know whether a string has all unique charachters, we need to know the information about the characters before the ith character we are examining. If we could use additional data structure, HashTable would be a very powerfull tool, finding a given character in O(1) time. Every time we meet a character in the string, we check the HashTable to make sure whether it has appeared before or not, if not, we add it into the HashTable and continue. However, we could not use additional data structure. So, we could use an array to "mimic" the HashTable. We assume that the string is ASCII, or if it is not, we could just make the array larger. Using a 256 boolean array to record each character, the character's ASCII value corresponds to index. We still obtain O(1) finding time. The algorithm's Time complexity is O(N), too, where N is the number of characters in string.

import java.util.*;

public class UniqueString {
    //Use HastTable to determine whether a character has ever showed, Time O(N), Space O(N)
    public boolean uniqueString(String s) {
        HashSet<Character> set = new HashSet<Character>();
        for(int i = 0; i < s.length(); i++) {
            if(set.contains(s.charAt(i)) == false) {
                set.add(s.charAt(i));
            }
            else return false;
        }
        return true;
    }
    //Use Boolean array to check whether each character has ever showed before, Time O(N), Space O(N)
    public boolean uniqueString2(String s) {
        boolean[] stat = new boolean[256];
        for(int i = 0; i < s.length(); i++) {
            if(stat[s.charAt(i)] == false) {
                stat[s.charAt(i)] = true;
            }
            else return false;
        }
        return true;
    }
    

    public static void main(String[] args) {
        UniqueString us = new UniqueString();
        System.out.println(us.uniqueString2(""));
        System.out.println(us.uniqueString2("a"));
        System.out.println(us.uniqueString2("aa"));
        System.out.println(us.uniqueString2("abcdefa"));
        System.out.println(us.uniqueString2("abc"));
    }
}

What other method can we obtain? We could use a two-loop to iterate each character and the substring infront of it to find whether this character has ever appeared. This use no extra space but require more time, which is an O(N2) algorithm. What's more, we could sort the string, and then compare each character and its neighbor, the time is O(NlogN), but the sort algorithm may use extra space.

 

However, there exists some ambiguous matters. Is the time complexity really O(N) only because we iterate the string? According to the drawer principle, when the string's length expands 256, there must exist two same characters, so the algorithm will never look for 258th, 259th, ..., nth character. So I think the amortized time complexity should be O(1), just the same with space complexity.