overview
Sword finger offer: the arrangement of strings, numbers that appear more than half in the array, the minimum number of k, and the median in the data stream
Android Foundation: Android message mechanism, Android event distribution mechanism
Sword finger offer
1.37 arrangement of strings
Enter a string and print out all the arrangements of characters in the string. You can return this string array in any order, but there can be no duplicate elements.
Example: Input: s = "abc" Output:["abc","acb","bac","bca","cab","cba"]
//Backtracking method class Solution { List<String> res = new LinkedList<>(); char[] c; public String[] permutation(String s) { c = s.toCharArray(); dfs(0); return res.toArray(new String[res.size()]); } void dfs(int x) { if(x == c.length - 1) { res.add(String.valueOf(c)); // Add arrangement scheme return; } HashSet<Character> set = new HashSet<>(); for(int i = x; i < c.length; i++) { if(set.contains(c[i])) continue; // Repeat, so prune set.add(c[i]); swap(i, x); // Swap, fix c[i] in bit x dfs(x + 1); // Turn on fixed x + 1 st character swap(i, x); // Restore exchange } } void swap(int a, int b) { char tmp = c[a]; c[a] = c[b]; c[b] = tmp; } }
1.38 numbers that appear more than half the times in the array
A number in the array appears more than half the length of the array. Please find this number.
You can assume that the array is non empty and that there are always many elements in a given array.
Example 1: input: [1, 2, 3, 2, 2, 2, 5, 4, 2] output: 2
//Moore voting method class Solution { public int majorityElement(int[] nums) { int votes = 0,x = 0; for(int e:nums){ if(votes == 0) x = e; if(e == x) votes++; else votes--; } return x; } } //If the given array does not necessarily have most elements, you need to traverse the array again, and record the times of x and compare it with half the length of the array.
1.39 minimum number of k
Enter the integer array arr to find the minimum number of k. For example, if you enter 8 numbers: 4, 5, 1, 6, 2, 7, 3 and 8, the minimum 4 numbers are 1, 2, 3 and 4.
Example 1: Input: arr = [3,2,1], k = 2 Output:[1,2] perhaps [2,1] Example 2: Input: arr = [0,1,2,1], k = 1 Output:[0]
//Based on the idea of fast scheduling //After each sentinel division, judge whether the index of the benchmark number in the array is equal to K. if true, directly return the first k numbers of the array at this time. class Solution { public int[] getLeastNumbers(int[] arr, int k) { if(k >= arr.length) return arr; return quickSort(arr,k,0,arr.length-1); } int[] quickSort(int[] arr,int k,int l,int r){ int i = l,j = r; while(i < j){ while(i < j && arr[j] >= arr[l]) j--; while(i < j && arr[i] <= arr[l]) i++; swap(arr,i,j); } swap(arr,i,l); if (i > k) return quickSort(arr, k, l, i - 1); if (i < k) return quickSort(arr, k, i + 1, r); return Arrays.copyOf(arr, k); } void swap(int[] arr,int i,int j){ int tmp = arr[i]; arr[i] = arr[j]; arr[j] = tmp; } }
1.40 median in data stream
How to get the median in a data stream? If an odd number of values are read out from the data stream, the median is the value in the middle after all values are sorted. If an even number of values are read from the data stream, the median is the average of the middle two numbers after all values are sorted
//heap //Set the large top heap and small top heap, and add them to the heap in turn each time. When the data flow is odd, the median is the top of the small top heap, otherwise the average of the two tops. class MedianFinder { Queue<Integer> A,B; /** initialize your data structure here. */ public MedianFinder() { A = new PriorityQueue<>(); // Small top pile, keep the larger half B = new PriorityQueue<>((x, y) -> (y - x)); // Large top pile, save the smaller half } public void addNum(int num) { if(A.size() != B.size()){ A.add(num); //Cyclic addition to ensure that the middle number of large top reactor is less than that of small top reactor B.add(A.poll()); }else{ B.add(num); A.add(B.poll()); } } public double findMedian() { return A.size() == B.size() ? (A.peek()+B.peek())/2.0 : A.peek(); } }
Android Foundation
Android message mechanism
When using the message mechanism in Android, the first thing we think of is handler. Handler is the upper interface of Android message mechanism. The process of using the handler is very simple. It can easily switch a task to the thread where the handler is located for execution. In general, the use scenario of handler is to update the UI.
Model of message mechanism
The Message mechanism mainly includes three parts: MessageQueue, Handler and Looper, and Message;
Message: the message to be delivered, which can deliver data;
MessageQueue: message queue, but its internal implementation is not a queue. In fact, it maintains the message list through a single linked list data structure, because the single linked list has advantages in insertion and deletion. The main functions are to deliver messages to the message pool (MessageQueue.enqueueMessage) and take messages from the message pool (MessageQueue.next);
Handler: Message auxiliary class, which is mainly used to send various message events (Handler.sendMessage) to the message pool and process corresponding message events (Handler.handleMessage);
Loop: continuously execute loop (loop. Loop), read the message from the MessageQueue, and distribute the message to the target handler according to the distribution mechanism.
Relationship among MessageQueue, Handler and Looper: there can only be one Looper in each thread, which is saved in ThreadLocal. The main thread (UI thread) has already created a Looper, so you do not need to create a Looper in the main thread, but you need to create a Looper in other threads. Each thread can have multiple handlers, that is, a Looper can process messages from multiple handlers. A MessageQueue is maintained in Looper to maintain the Message queue. Messages in the Message queue can come from different handlers.
principle
Looper:
loop() enters the loop mode and repeats the following operations until the Message is empty: read the next Message of MessageQueue (about next(), which will be described in detail later); Distribute the Message to the corresponding target. When * * next() * * takes out the next Message, and there is no Message in the queue, next() will loop indefinitely and cause blocking. Wait for a Message to be added to the MessageQueue, and then wake up again.
Handler:
For the parameterless construction method of Handler, the Looper object in the TLS of the current thread is adopted by default, the callback callback method is null, and the message is processed synchronously. Just execute Looper Prepare () method, you can get a valid Looper object.
Send message:
There are several ways to send messages, but in the final analysis, the sendMessageAtTime() method is called. When sending a message through the Handler's post() method or send() method in the child thread, the sendMessageAtTime() method is finally called.
The function of sendMessageAtTime() method is very simple. It is to call the enqueueMessage() method of MessageQueue to add a message to the message queue.
MessageQueue is arranged according to the sequence of Message trigger time, and the Message at the head of the queue is the Message to be triggered the earliest. When a Message needs to be added to the Message queue, it will traverse from the queue header until it finds the appropriate location where the Message should be inserted, so as to ensure the chronological order of all messages.
Get message:
After sending the message, maintain the message queue in the MessageQueue, and then continuously obtain the message through the loop() method in the loop. The loop() method is introduced above, and the most important one is to call queue Next () method, which extracts the next piece of information
The next() method obtains the next message to be executed according to the trigger time of the message. When the message in the queue is empty, the blocking operation will be performed.
Distribute message:
In the loop() method, after getting the next message, execute MSG target. Dispatchmessage (MSG) to distribute the message to the target Handler object.
When MSG When callback is not empty, the callback method MSG callback. run() ;
When the Handler's mCallback is not empty, the callback method mCallback handleMessage(msg) ;
Finally, calling the callback method handleMessage() of Handler itself, the method is empty by default, and the Handler subclass completes the specific logic by overwriting this method.
Summary:
When sending a message, the message contains the reference of the current handler. Add the message to the MessageQueue, loop takes out the header message, and callback the handler's handleMessage() method by viewing the reference of the target handler in the message to receive the message;
The Handler is responsible for sending and processing messages, and the Looper is responsible for receiving the messages sent by the Handler and directly returning the messages to the Handler itself (handleMessage). The MessageQueue is a container for storing messages and is a one-way linked list structure (the addition and deletion of a single linked list has advantages over the queue).
Android event distribution mechanism
summary
1. Start to understand various mechanisms and encapsulation classes of Android; First, preliminarily understand the principle, master the use method, and try to understand the source code.