[algorithm interview question series] detailed analysis: the first non repetitive character in the character stream (two methods) and the entry node of the link in the linked list

Posted by remlabm on Mon, 27 Dec 2021 00:17:19 +0100

First non repeating character in JZ54 character stream

(medium)

subject

describe
Please implement a function to find the first character that appears only once in the character stream. For example, when only the first two characters "go" are read out from the character stream, the first character that appears only once is "g". When the first six characters "google" are read from the character stream, the first character that appears only once is "l".
The background will call the Insert and firstapperingonce functions in the following ways

Return value Description:
Returns # characters if there is no one occurrence character in the current character stream.

Example
Input:
"google"
Return value:
"ggg#ll"

thinking

The idea of this question is not difficult, just use

  • A hash map: to record the number of occurrences of each character in the current string
  • A queue (or stack or string or array): used to make the current results sequential (because the title requires to return the first non repeating character, and the set of keys in the hash map is unordered, an ordered "container" is needed to assist in recording the characters that currently appear only once. If there is no one, it is' # ')

Of course, the queue is only used to solve the problem that the set of keys in the hash map is out of order. Naturally, we can think of using LinkedHashMap as an internal implementation of orderly key value pairs, so that there is no need to use an auxiliary "container".

It can be seen that the idea is very simple and there are two main implementation methods. However, when I think clearly and prepare to start writing, I find that this problem is a code template that needs to be strictly executed by the card background test, which makes it very inflexible to write this problem.

The background template is as follows:

Method 1: HashMap + queue

This method needs to consider many special situations. I tried to write:


After that, it was changed again, but there was still a problem, so this method was easy to make mistakes, or there was a problem with my writing

(the following code is not submitted correctly, but there is still a problem. It has taken too much time and is not going to be changed, but it is also an idea)

class JZ54 The first non repeating character 2 in the character stream {
    LinkedList<Character> list = new LinkedList();
    HashMap<Character, Integer> map = new HashMap<>();

    //Insert one char from stringstream
    public void Insert(char ch) {
        if (!map.containsKey(ch)) {
            map.put(ch, 1);
            //The current element does not exist, but a more advanced element may exist before. We need to judge
            if (list.size() > 0) {
                if (list.getLast() == '#'{/ / no matching element exists before' / '
                    list.add(ch);
                } else { //There was a previously compliant
                    list.add(list.getLast());
                }
            } else {
                list.add(ch);
            }
        } else {
            map.put(ch, -1);
            //If the current character element already exists and is equal to the last one in the list
            if (list.getLast() == ch) {
                list.add('#');
            } else { //If the current character element already exists and is not equal to the last one in the list, if there is another matching element before, let it act as this position
                boolean flag = false;
                for (int i = 0; i < list.size(); i++) {
                    if (list.get(i) == 1) {
                        list.add(list.get(i));
                        flag = true; //find
                        break;
                    }
                }
                if (!flag) { //Can't find
                    list.add('#');
                }

            }
        }
    }

    //return the first appearence once char in current stringstream
    public char FirstAppearingOnce() {
        return list.getLast();
    }
}

Method 2: LinkedHashMap

[implementation]

public class JZ54 The first non repeating character in the character stream {

    Map<Character, Integer> map = new LinkedHashMap(); //Hash

    //Insert one char from stringstream
    public void Insert(char ch) {
        if(map.containsKey(ch)) {
            map.put(ch,-1);
        } else {
            map.put(ch, 1);
        }
    }

    //return the first appearence once char in current stringstream
    public char FirstAppearingOnce() {
        Iterator<Character> iterator = map.keySet().iterator();
        while (iterator.hasNext()) {
            char cur = iterator.next();
            if(map.get(cur) == 1) {
                return cur;
            }
        }
        return '#';
    }
}

JZ55 entry node of link in linked list

(medium)

subject

describe
For a linked list, if it contains a ring, please find the entry node of the ring of the linked list. Otherwise, null is returned.


Enter Description:
The input is divided into two segments. The first segment is the linked list before entering the ring, and the second segment is the linked list ring. These two will be assembled into a ring or acyclic single linked list in the background
Return value Description:
Return the entry node of the link of the linked list. And our daemon will print this node

Example 1
Input:
{1,2},{3,4,5}
Return value:
3
explain:
Return to the circular linked list entry node. We will print the circular linked list entry node in the background, that is, 3

Example 2
Input:
{1},{}
Return value:
"null"
explain:
If there is no ring, null is returned, and "null" is printed in the background

Example 3
Input:
{},{2}
Return value:
2
explain:
Only ring linked list node 2, return node 2, background print 2

thinking

At the beginning, I didn't understand the time difference. Fortunately, I just played yoyo a few days ago. I suddenly understood it. The meaning is roughly as shown in the figure below. Take inputting {1,2}, {3,4,5} as an example:

After understanding the meaning of the question, it is not difficult to find the entry node of the ring, that is, when traversing the linked list, return the first repeated node (it must not be judged by the repetition of the value, but by whether the reference of the node object is repeated).

realization

HashSet<ListNode> set = new HashSet();

    public ListNode EntryNodeOfLoop(ListNode pHead) {
        if (pHead == null) {
            return null;
        }

        //You can continue traversal only if it does not exist
        while (pHead != null && !set.contains(pHead)) {
            set.add(pHead);
            pHead = pHead.next;
        }

        return pHead;
    }

Topics: Java Algorithm data structure