剑指 Offer II 085. 生成匹配的括号(22. 括号生成)(中等)
// 思路:每一个节点分叉要加 “(” 还是 “)”,加“)”前提需要有一定数的左括号进行配对
// 剪枝:left 不能超过 n
// 10:16 - 10:25
class Solution {
public List<String> generateParenthesis(int n) {
List<String> res = new ArrayList<>();
dfs(res,new String(),0,0,n);
return res;
}
public void dfs(List<String> res,String current, int left,int leftSum,int n){
if(leftSum==n&&left==0){
res.add(new String(current));
return ;
}
if(left>0)dfs(res,current+')',left-1,leftSum,n);
if(leftSum<n)dfs(res,current+'(',left+1,leftSum+1,n);
}
}
103. 二叉树的锯齿形层序遍历(中等)
// 10:29 - 10:40
// 思路:带 for 的层序遍历,在特定层需要反转一下
class Solution {
public List<List<Integer>> zigzagLevelOrder(TreeNode root) {
List<List<Integer>> res = new ArrayList<>();
if(root==null)return res;
Queue<TreeNode> queue = new LinkedList<>();
queue.offer(root);
boolean flag = false;
while(!queue.isEmpty()){
List<Integer> tp = new ArrayList<>();
int n = queue.size();
for(int i=0;i<n;i++){
TreeNode node = queue.poll();
tp.add(node.val);
if(node.left!=null)queue.offer(node.left);
if(node.right!=null)queue.offer(node.right);
}
if(flag)Collections.reverse(tp);
res.add(tp);
flag = !flag;
}
return res;
}
}
剑指 Offer II 076. 数组中的第 k 大的数字(中等)
通过这个题目练习快排和归并
// 快排做法
// 10:46 - 11:10
class Solution {
public int findKthLargest(int[] nums, int k) {
return quicksort(nums,0,nums.length-1,nums.length-k);
}
public int quicksort(int[] nums,int left,int right,int k){
int p = partation(nums,left,right);
if(p==k)
return nums[p];
else {
return k<p?quicksort(nums,left,p-1,k):quicksort(nums,p+1,right,k);
}
}
public int partation(int[] nums,int left,int right){
int key = nums[left];
while(left<right){
while(nums[right]>=key&&right>left)right--;
nums[left] = nums[right];
while(nums[left]<=key&&right>left)left++;
nums[right] = nums[left];
}
nums[left] = key;
return left;
}
}
// 堆排做法: 11:11 - 11:33
class Solution {
public int findKthLargest(int[] nums, int k) {
return heapsort(nums,k);
}
public int heapsort(int[] nums, int k){
int n = nums.length;
for(int i=0;i<k;i++){
heapAdjust(nums,n-1-i);
swap(nums,0,n-1-i);
}
return nums[n-k];
}
public void heapAdjust(int[] nums,int len){
for(int i=(len-1)/2;i>=0;i--){
for(int j = i*2+1;j<=len;j=j*2+1){
if(j+1<=len&&nums[j+1]>nums[j])j++;
if(nums[j]>nums[(j-1)/2])swap(nums,j,(j-1)/2);
}
}
}
public void swap(int a[],int x,int y){
int temp = a[x];
a[x] = a[y];
a[y] = temp;
}
}
// 归并做法,归并并不能优化做法,只是练手 11:33 - 11:53
class Solution {
public int findKthLargest(int[] nums, int k) {
int n = nums.length;
mergeSort(nums,0,n-1);
return nums[n-k];
}
public void mergeSort(int[] nums,int left,int right){
if(left>=right)return ;
int mid = left + (right - left)/2;
mergeSort(nums,left,mid);
mergeSort(nums,mid+1,right);
merge(nums,left,right);
}
public void merge(int[] nums,int left,int right){
int mid = left + (right - left)/2;
int i = left,j = mid+1,it = 0;
int temp[] = new int[right-left+1];
while(i<=mid && j <=right){
if(nums[i]<nums[j])temp[it++] = nums[i++];
else temp[it++] = nums[j++];
}
while(i<=mid)temp[it++] = nums[i++];
while(j<=right)temp[it++] = nums[j++];
for(int k=0;k<temp.length;k++){
nums[left+k] = temp[k];
}
}
}