Substring with of All Words
Permutations II ( 这个以前自己写了三种思路,刚刚竟然一种都没想起来,艹)
Wildcard Matching
N-Queens II
Largest Rectangle in Histogram
Permutation Sequence
Valid Number
sqrt()
Given an integer array nums, find the contiguous subarray within an array (containing at least one number) which has the largest product.
Example 1:
Input: [2,3,-2,4]
Output: 6
Explanation: [2,3] has the largest product 6.
Example 2:
Input: [-2,0,-1] Output: 0 Explanation: The result cannot be 2, because [-2,-1] is not a subarray.
public class Solution {
public int maxProduct(int[] A) {
assert(A!=null && A.length >0);
if(A.length == 1)
return A[0];
int result = Integer.MIN_VALUE, maxEndHere = 1;// max positive product ending at the current position
int minEndHere = 1;// min negative product ending at the current position
for (int i = 0; i < A.length; i++) {
if (A[i] > 0) {
maxEndHere = maxEndHere * A[i];
minEndHere = Math.min(minEndHere * A[i],1);
result = Math.max(result,maxEndHere);
} else if(A[i]==0) {
maxEndHere = 1;
minEndHere = 1;
result = Math.max(result,0);// 0 can also be a product result
}else{ // A[i]<0
result = Math.max(minEndHere*A[i],result);
int tmp = maxEndHere;
maxEndHere = Math.max( minEndHere*A[i],1);
minEndHere = tmp*A[i];
}
}
return result;
}
}
Mistakes: 
Input: Two arrays that represent Inorder
and level order traversals of a
Binary Tree
in[] = {4, 8, 10, 12, 14, 20, 22};
level[] = {20, 8, 22, 4, 12, 10, 14};
Output: Construct the tree represented
by the two arrays.
For the above two arrays, the
constructed tree is shown in
the diagram on right side
思想就是每次在level order中,提取first node 作为当前的root。
然后,在in order中找到所有在其前面的值(作为左子树)。同时在level order的数组中抽取所有左子树的value。
same for the right subtree.
repeat above .
We strongly recommend to minimize the browser and try this yourself first.
20
/ \
/ \
{4,8,10,12,14} {22}
Let us call {4,8,10,12,14} as left subarray in Inorder traversal and {22} as right subarray in Inorder traversal.// Recur for following arrays to construct the left subtree
In[] = {4, 8, 10, 12, 14}
level[] = {8, 4, 12, 10, 14}
Similarly, we recur for following two arrays and construct the right subtree.
// Recur for following arrays to construct the right subtree
In[] = {22}
level[] = {22}
Following is C++ implementation of the above approach. /* program to construct tree using inorder and levelorder traversals */#include <iostream>using namespace std;/* A binary tree node */struct Node{ int key; struct Node* left, *right;};/* Function to find index of value in arr[start...end] */int search(int arr[], int strt, int end, int value){ for (int i = strt; i <= end; i++) if (arr[i] == value) return i; return -1;}// n is size of level[], m is size of in[] and m < n. This// function extracts keys from level[] which are present in// in[]. The order of extracted keys must be maintainedint *extrackKeys(int in[], int level[], int m, int n){ int *newlevel = new int[m], j = 0; for (int i = 0; i < n; i++) if (search(in, 0, m-1, level[i]) != -1) newlevel[j] = level[i], j++; return newlevel;}/* function that allocates a new node with the given key */Node* newNode(int key){ Node *node = new Node; node->key = key; node->left = node->right = NULL; return (node);}/* Recursive function to construct binary tree of size n from Inorder traversal in[] and Level Order traversal level[]. inSrt and inEnd are start and end indexes of array in[] Initial values of inStrt and inEnd should be 0 and n -1. The function doesn't do any error checking for cases where inorder and levelorder do not form a tree */Node* buildTree(int in[], int level[], int inStrt, int inEnd, int n){ // If start index is more than the end index if (inStrt > inEnd) return NULL; /* The first node in level order traversal is root */ Node *root = newNode(level[0]); /* If this node has no children then return */ if (inStrt == inEnd) return root; /* Else find the index of this node in Inorder traversal */ int inIndex = search(in, inStrt, inEnd, root->key); // Extract left subtree keys from level order traversal int *llevel = extrackKeys(in, level, inIndex, n); // Extract right subtree keys from level order traversal int *rlevel = extrackKeys(in + inIndex + 1, level, n-inIndex-1, n); /* construct left and right subtress */ root->left = buildTree(in, llevel, inStrt, inIndex-1, n); root->right = buildTree(in, rlevel, inIndex+1, inEnd, n); // Free memory to avoid memory leak delete [] llevel; delete [] rlevel; return root;}/* Uti;ity function to print inorder traversal of binary tree */void printInorder(Node* node){ if (node == NULL) return; printInorder(node->left); cout << node->key << " "; printInorder(node->right);}/* Driver program to test above functions */int main(){ int in[] = {4, 8, 10, 12, 14, 20, 22}; int level[] = {20, 8, 22, 4, 12, 10, 14}; int n = sizeof(in)/sizeof(in[0]); Node *root = buildTree(in, level, 0, n - 1, n); /* Let us test the built tree by printing Insorder traversal */ cout << "Inorder traversal of the constructed tree is \n"; printInorder(root); return 0;} |
Inorder traversal of the constructed tree is 4 8 10 12 14 20 22An upper bound on time complexity of above method is O(n3). In the main recursive function, extractNodes() is called which takes O(n2) time.
Let the given string be "banana".
0 banana 5 a
1 anana Sort the Suffixes 3 ana
2 nana ----------------> 1 anana
3 ana alphabetically 0 banana
4 na 4 na
5 a 2 nana
The suffix array for "banana" is {5, 3, 1, 0, 4, 2}
We have discussed Naive algorithm for construction of suffix array.
The Naive algorithm is to consider all suffixes, sort them using a
O(nLogn) sorting algorithm and while sorting, maintain original indexes.
Time complexity of the Naive algorithm is O(n2Logn) where n is the number of characters in the input string.Index Suffix Rank 0 banana 1 1 anana 0 2 nana 13 3 ana 0 4 na 13 5 a 0For every character, we also store rank of next adjacent character, i.e., the rank of character at str[i + 1] (This is needed to sort the suffixes according to first 2 characters). If a character is last character, we store next rank as -1
Index Suffix Rank Next Rank 0 banana 1 0 1 anana 0 13 2 nana 13 0 3 ana 0 13 4 na 13 0 5 a 0 -1Sort all Suffixes according to rank and adjacent rank. Rank is considered as first digit or MSD, and adjacent rank is considered as second digit.
Index Suffix Rank Next Rank 5 a 0 -1 1 anana 0 13 3 ana 0 13 0 banana 1 0 2 nana 13 0 4 na 13 0Sort according to first four character
Index Suffix Rank 5 a 0 [Assign 0 to first] 1 anana 1 (0, 13) is different from previous 3 ana 1 (0, 13) is same as previous 0 banana 2 (1, 0) is different from previous 2 nana 3 (13, 0) is different from previous 4 na 3 (13, 0) is same as previousFor every suffix str[i], also store rank of next suffix at str[i + 2]. If there is no next suffix at i + 2, we store next rank as -1
Index Suffix Rank Next Rank 5 a 0 -1 1 anana 1 1 3 ana 1 0 0 banana 2 3 2 nana 3 3 4 na 3 -1Sort all Suffixes according to rank and next rank.
Index Suffix Rank Next Rank 5 a 0 -1 3 ana 1 0 1 anana 1 1 0 banana 2 3 4 na 3 -1 2 nana 3 3We stop here as the next value is 8 which is greater than number of characters in “banana”.
// C++ program for building suffix array of a given text#include <iostream>#include <cstring>#include <algorithm>using namespace std;// Structure to store information of a suffixstruct suffix{ int index; // To store original index int rank[2]; // To store ranks and next rank pair};// A comparison function used by sort() to compare two suffixes// Compares two pairs, returns 1 if first pair is smallerint cmp(struct suffix a, struct suffix b){ return (a.rank[0] == b.rank[0])? (a.rank[1] < b.rank[1] ?1: 0): (a.rank[0] < b.rank[0] ?1: 0);}// This is the main function that takes a string 'txt' of size n as an// argument, builds and return the suffix array for the given stringint *buildSuffixArray(char *txt, int n){ // A structure to store suffixes and their indexes struct suffix suffixes[n]; // Store suffixes and their indexes in an array of structures. // The structure is needed to sort the suffixes alphabatically // and maintain their old indexes while sorting for (int i = 0; i < n; i++) { suffixes[i].index = i; suffixes[i].rank[0] = txt[i] - 'a'; suffixes[i].rank[1] = ((i+1) < n)? (txt[i + 1] - 'a'): -1; } // Sort the suffixes using the comparison function // defined above. sort(suffixes, suffixes+n, cmp); // At his point, all suffixes are sorted according to first // 2 characters. Let us sort suffixes according to first 4 // characters, then first 8 and so on int ind[n]; // This array is needed to get the index in suffixes[] // from original index. This mapping is needed to get // next suffix. for (int k = 4; k < n; k = k*2) { // Assigning rank and index values to first suffix int rank = 0; suffixes[0].rank[0] = rank; ind[suffixes[0].index] = 0; int prev_rank = suffixes[0].rank[0]; // Assigning rank to suffixes for (int i = 1; i < n; i++) { // If first rank and next ranks are same as that of previous // suffix in array, assign the same new rank to this suffix if (suffixes[i].rank[0] == prev_rank && suffixes[i].rank[1] == suffixes[i-1].rank[1]) { prev_rank = suffixes[i].rank[0]; suffixes[i].rank[0] = rank; } else // Otherwise increment rank and assign { prev_rank = suffixes[i].rank[0]; suffixes[i].rank[0] = ++rank; } ind[suffixes[i].index] = i; } // Assign next rank to every suffix for (int i = 0; i < n; i++) { int nextindex = suffixes[i].index + k/2; suffixes[i].rank[1] = (nextindex < n)? suffixes[ind[nextindex]].rank[0]: -1; } // Sort the suffixes according to first k characters sort(suffixes, suffixes+n, cmp); } // Store indexes of all sorted suffixes in the suffix array int *suffixArr = new int[n]; for (int i = 0; i < n; i++) suffixArr[i] = suffixes[i].index; // Return the suffix array return suffixArr;}// A utility function to print an array of given sizevoid printArr(int arr[], int n){ for (int i = 0; i < n; i++) cout << arr[i] << " "; cout << endl;}// Driver program to test above functionsint main(){ char txt[] = "banana"; int n = strlen(txt); int *suffixArr = buildSuffixArray(txt, n); cout << "Following is suffix array for " << txt << endl; printArr(suffixArr, n); return 0;} |
Following is suffix array for banana 5 3 1 0 4 2Note that the above algorithm uses standard sort function and therefore time complexity is O(nLognLogn). We can use Radix Sort here to reduce the time complexity to O(nLogn).
Given a binary tree, print out the tree in level order (ie, from left to right, level by level). Output a newline after the end of each level. Breadth First Search (BFS) is not allowed.
3 / \ 9 20 / \ 15 7For example, the level order output of the tree above is:
3 9 20 15 7
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
void printLevel(BinaryTree *p, int level) {
if (!p) return;
if (level == 1) {
cout << p->data << " ";
} else {
printLevel(p->left, level-1);
printLevel(p->right, level-1);
}
}
void printLevelOrder(BinaryTree *root) {
int height = maxHeight(root);
for (int level = 1; level <= height; level++) {
printLevel(root, level);
cout << endl;
}
}
|
T(k) = 2T(k-1) + c
= 2k-1 T(1) + c
= 2k-1 + c
Assuming it’s a balanced binary tree, then it would have a total of lg N levels.T(1) + T(2) + ... + T(lg N) = 1 + 2 + 22 + ... + 2lg N-1 + c = O(N)Finding the maximum height of the tree also takes O(N) time, therefore the overall complexity is still O(N).