初级算法(九)----- 树、排序和搜索
1、引言
1、将有序数组转换为二叉搜索树:二叉搜索树每个节点的左右两个字数的高度差的绝对值不超过1
2、合并两个有序数组
3、第一个错误的版本
2、将有序数组转换为二叉搜索树
这题可以采用递归的方式进行,由于数组是有序的,每次选取中间的节点作为根,如此构造出的二叉树就是二叉搜索树。
/**
* 方法一:采用递归做
* 每次都选中间值做为节点
* @param nums
* @return
* 执行用时: 0ms,内存消耗:41.5MB
*/
public TreeNode sortedArrayToBST(int[] nums) {
int length=nums.length;
if(length==0)
return null;
return sortedArrayToBSTHelper(nums,0,length-1);
}
public TreeNode sortedArrayToBSTHelper(int[] nums,int firstIndex,int lastIndex){
if(firstIndex>lastIndex)
return null;
int mid=(lastIndex+firstIndex)/2;
TreeNode root =new TreeNode(nums[mid]);
root.right=sortedArrayToBSTHelper(nums,mid+1,lastIndex);
root.left=sortedArrayToBSTHelper(nums,firstIndex,mid-1);
return root;
}
3、合并两个有序数组
这个很简单,只是需要一个有序数组的空间,这个数组存放的就是生成后的有序数组。
/**
* 方法一
* 合并两个有序数组
* 思路:利用第三个数组存储,加一个循环进行对比,最后还剩的数据全部加入到temp数组中
* @param nums1
* @param m
* @param nums2
* @param n
* 执行用时:0ms,内存消耗:41.3MB
*/
public void merge(int[] nums1, int m, int[] nums2, int n) {
if(n==0)
return;
int[] temp=new int[m+n];
int i=0;
int j=0;
int k=0;
while(i<m && j<n){
if(nums1[i]<nums2[j]){
temp[k]=nums1[i];
i++;
k++;
}else{
temp[k]=nums2[j];
j++;
k++;
}
}
if(i<m){
for (int l = k; l <m+n && i<=m; l++,i++) {
temp[l]=nums1[i];
}
}
if(j<n){
for (int l = k; l <m+n && j< n; l++,j++) {
temp[l]=nums2[j];
}
}
for (int l = 0; l < m+n; l++) {
nums1[l]=temp[l];
}
}
第二种方法就是利用官方的api,这题没涉及任何算法。
/**
* 方法二
* 使用官方api
* @param nums1
* @param m
* @param nums2
* @param n
* 执行用时:1ms,内存消耗:41.5MB
*/
public void merge2(int[] nums1, int m, int[] nums2, int n) {
System.arraycopy(nums2,0,nums1,m,n);
Arrays.sort(nums1);
}
4、第一个错误的版本
题目说明:在一个版本数组中寻找第一个错误的版本。方法一:采用的就是递归方法
/**
* 方法一
* 采用递归
* @param n
* @return
* 执行用时:14ms,内存消耗:38MB
*/
public int firstBadVersion(int n) {
if(n==1)
return n;
if(isBadVersion(1))
return 1;
return firstBadVersionHelper(1,n);
}
public int firstBadVersionHelper(int first,int end) {
if(end-first==1)
return end;
int mid= first+(end-first)/2;
if(isBadVersion(mid)){
return firstBadVersionHelper(first,mid);
}else{
return firstBadVersionHelper(mid,end);
}
}
第二中方法就是二分查找,进行不断计算和比较。
/**
* 方法二
* 思路:二分查找
* @param n
* @return
* 执行用时:11ms,内存消耗:38MB
*/
public int firstBadVersion2(int n) {
int start=1;
int end=n;
while(start<end){
int mid=start+(end-start)/2;
if(!isBadVersion(mid)){
start=mid+1;
}else{
end=mid;
}
}
return start;
}