-
Notifications
You must be signed in to change notification settings - Fork 0
#132 #4
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
#132 #4
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,48 @@ | ||
| /** | ||
| 132. Palindrome Partitioning II | ||
|
|
||
| Given a string s, partition s such that every substring of the partition is a palindrome. | ||
|
|
||
| Return the minimum cuts needed for a palindrome partitioning of s. | ||
|
|
||
| For example, given s = "aab", | ||
| Return 1 since the palindrome partitioning ["aa","b"] could be produced using 1 cut. | ||
| **/ | ||
|
|
||
|
|
||
| /** | ||
| create a int array minCut to cache the minimum cuts needed for a palindrome partition for string from position j to the | ||
| end, initialize it with maximum number of possible cuts: length of substring - 1 | ||
|
|
||
| minCut[0] is the minimum cuts needed for a palindrome partition for the entire string, namely what we want to return | ||
|
|
||
| create a 2-d boolean array to cache whether string is palindrome from position j to position i | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same here. Is it [i][j] or [j][i]?
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. substring from j to i
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Still unclear. So what I really want to know is for substring from j to i, will it be stored at [i][j] or [j][i]. You can't always assume [i][j] convention. Be clear. |
||
|
|
||
| for substring from position j to the end: | ||
| try every partition possible i: | ||
| if substring(j, i) is palindrome, as long as minimum cut cached is smaller than 1 + minimum cut for substring(i, end), update it | ||
| edge case: if i reaches to end of string, then no minimum cut is needed for substring(j, i) | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't understand this sentence.
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. DP transition function: minCut[j] = Math.min(minCut[j], minCut[i] + 1) && isPalindrome[j][i] == true |
||
| **/ | ||
|
|
||
| public int minCut(String s) { | ||
| if(s == null || s.length() <= 1) return 0; | ||
| int n = s.length(); | ||
| int[] minCut = new int[n]; | ||
| boolean[][] isPalindrome = new boolean[n][n]; | ||
|
|
||
| for(int j = n - 1; j >= 0; j--){ | ||
| minCut[j] = n - j - 1; | ||
| for(int i = j; i < n; i++){ | ||
| if(s.charAt(j) == s.charAt(i) && ((j + 1 >= i - 1) || isPalindrome[j + 1][i - 1])){ | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't like the (j+1 >= i-1) here. Because you basically are using edge cases as base cases. More condition in if statement, more likely you will make a mistake during the interview.
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Any idea how I can avoid it?
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So think about this, what is isPalindrome[i][i]? That should be a simple answer and you can initialize that at the beginning. In that case, if you initialize that, can you avoid this if condition? |
||
| isPalindrome[j][i] = true; | ||
| if(i == n - 1) minCut[j] = 0; | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. See? Another if here and another edge case.
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Any hint?
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Think what do you really mean by (i == n - 1)? Actually, you can initialize all minCut to be 0 at beginning. Then you won't have this if statement at all. |
||
| else minCut[j] = Math.min(minCut[j], minCut[i + 1] + 1); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| return minCut[0]; | ||
| } | ||
|
|
||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,106 @@ | ||
| /** | ||
| Write a program to examine the outputs from a sequence of operations on a data structure called a single-output deque, and deduce the sequence of operations that produced that output. | ||
|
|
||
| An ordinary deque is data structure that represents a list and supports the following four operations: | ||
| pushFront(x): add x to the beginning of the list so that it becomes the first element of the list | ||
| pushBack(x): add x to the end of the list so that it becomes the last element of the list | ||
| popFront(): remove and return the first element of the list | ||
| popBack(): remove and return the last element of the list | ||
|
|
||
| In this problem, we are considering the behavior of a single-output deque, which is the same as a deque except that it supports only pushFront, pushBack, and popBack. | ||
| Furthermore, we modify pushFront and pushBack so that they do not accept an argument. Instead, pushFront and pushBack push the contents of a counter (whose initial value is 1) to the beginning or end of the deque and increment the counter. | ||
|
|
||
| Consider the following examples: | ||
| (pushBack, pushBack, pushFront) results in the following sequence of list states: | ||
| (1) | ||
| (1, 2) | ||
| (3, 1, 2) | ||
| (pushFront, pushFront, pushBack, popBack, pushBack, popBack) results in the following sequence of states and outputs: | ||
| (1) | ||
| (2, 1) | ||
| (2, 1, 3) | ||
| (2, 1) output: 3 | ||
| (2, 1, 4) | ||
| (2, 1) output 4 | ||
| In the previous example, the output of the entire sequence of operations can be written as (3, 4). | ||
| Your program will receive exactly one line of input, a comma-separated list of integers with no spaces in the following format: | ||
| x_1,x_2,...,x_N | ||
| where 1 <= N <= 100,000 and the sequence (x_1, x_2,..., x_N) is a permutation of the set of integers {1, 2,..., N} (i.e., the sequence is not empty, and there are no repeated or missing values). | ||
| Your program should produce exactly one line of output, a comma-separated list of operations with no spaces in the following format: | ||
| op_1,op_2,...,op_2N | ||
| where each op_i is a string from the set {pushFront, pushBack, popBack}. The output of the sequence of operations (op_1, op_2,..., op_2N) should be the sequence (x_1, x_2,..., x_N). If it is not possible to produce the output (x_1, x_2,..., x_N) with any sequence of single-output deque operations, simply print the string “impossible”. If there are multiple sequences of operations that result in the sequence received in the input, choose the output that is smallest lexicographically, ordered by standard alphabetical ordering. | ||
|
|
||
| Sample Testcases | ||
| Input: | ||
| 3,2,1 | ||
| Output: | ||
| pushBack,pushBack,pushBack,popBack,popBack,popBack | ||
|
|
||
| Input: | ||
| 1,2,3 | ||
| Output (note choice of pushBack over pushFront): | ||
| pushBack,popBack,pushBack,popBack,pushBack,popBack | ||
|
|
||
| Input: | ||
| 4,1,5,2,3 | ||
| Output (pushFront is needed in some cases): | ||
| pushBack,pushFront,pushFront,pushBack,popBack,popBack,pushBack,popBack,popBack,popBack | ||
|
|
||
| Input: | ||
| 5,1,4,2,3 | ||
| Output (some sequences are impossible): | ||
| impossible | ||
|
|
||
| To help with solving this problem in a timely manner, we provide the following hints that may help you work out one way of writing an efficient program to solve this problem: | ||
| 1. Note that if the first element of the input sequence is 4, then the 5th element of the output must be popBack (unless the output is impossible). The reason for this is that | ||
| at least 4 pushes must be executed to get 4 into the deque, and the 4th push must be a pushBack so that 4 is ready to be popped from the back of the deque. More than 4 pushes | ||
| could be executed, but elements 5 and above must be pushed to the front, and this could easily be done after 4 was popped instead of before. Since popBack is lexicographically | ||
| smaller than pushFront, we prefer to execute popBack as early as possible. | ||
| 2. Consider simulating the deque as a way to efficiently determine which operations were performed on it. For example, as above, if the first element of the input is a 4, | ||
| simulate a deque having the elements 1 through 4 pushed into it. Since you do not know whether each element was pushed to the front or the back, try pushing it on both sides | ||
| and figuring out which side is correct later in the simulation. | ||
| **/ | ||
|
|
||
| //All of the number show in order (from 1 to n) | ||
| //If a number x is shown, then all of the numbers before x should all been added to deque as well. For current number x, | ||
| //loop over all numbers smaller than or equal to x, if its order is before x, then push to back of queue; if its order is after x, then push to the front of queue. | ||
| //If the last element of queue equals to current number, pop back the last element; else output "impossible" | ||
|
|
||
| public static void main(String[] args){ | ||
| Scanner sc = new Scanner(System.in); | ||
| String input = sc.nextLine(); | ||
| String[] strs = strs.split(","); | ||
| int n = strs.length; | ||
| int[] nums = new int[n]; | ||
| for(int i = 0; i < n; i++){ | ||
| nums[i] = Integer.parseInt(strs[i]); | ||
| } | ||
| int[] order = new int[n + 1]; | ||
| for(int i = 0; i < n; i++){ | ||
| order[nums[i]] = i; | ||
| } | ||
| Deque<Integer> deque = new LinkedList<>(); | ||
| StringBuilder output = new StringBuilder(); | ||
| for(int i = 1, j = 0; j < n; j++){ | ||
| for(; i <= nums[j]; i++){ | ||
| if(deque.isEmpty() || order[deque.peekLast()] > order[i]){ | ||
| deque.offerLast(i); | ||
| output.append("pushBack,"); | ||
| } | ||
| else{ | ||
| deque.offerFirst(i); | ||
| output.append("pushFront,"); | ||
| } | ||
| } | ||
| if(deque.isEmpty() || (deque.peekLast() != nums[j])){ | ||
| System.out.print("impossible"); | ||
| } | ||
| deque.pollLast(); | ||
| output.append("popBack,"); | ||
| } | ||
| System.out.print(output.toString().substring(0, output.length() - 1)); | ||
| return; | ||
| } | ||
|
|
||
|
|
||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Alright, I am now picky about your explanation here. So you said "minimum cuts needed for a palindrome...from j to the end...", where is that stored? All at minCut[0] or minCut[1]? where is it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
minCut[j] stores the minimum cuts needed for a palindrome partition for substring from index j to the end of string, thus minCut[0] stands for the minimum cuts needed for a palindrome partition for substring starting with index 0, the entire string.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's better.