题目1、整数转罗马数字
题解
基本就是打表…
class Solution {
public String intToRoman(int num) {
StringBuffer sb=new StringBuffer();
int[] rom=new int[]{1000,900,500,400,100,90,50,40,10,9,5,4,1};
String[] value=new String[]{"M","CM","D","CD","C","XC","L","XL","X","IX","V","IV","I"};
for(int i=0;i<13;i++){
int c=num/rom[i];
while(c!=0&&num>0){
sb.append(value[i]);
num-=rom[i];
c=num/rom[i];
}
}
return sb.toString();
}
}
时间复杂度: O ( 1 ) O(1) O(1)
空间复杂度: O ( 1 ) O(1) O(1)
题目2、在排序数组中查找元素的第一个和最后一个位置
题解
顺序查找
class Solution {
public int[] searchRange(int[] nums, int target) {
int n=nums.length;
int[] res=new int[]{-1,-1};
if(n==0)
return res;
for(int i=0;i<n;i++){
while(i<n&&nums[i]==target){
if(res[0]==-1)
res[0]=i;
i++;
}
if(res[0]!=-1){
res[1]=i-1;
break;
}
}
return res;
}
}
时间复杂度: O ( n ) O(n) O(n)
空间复杂度: O ( 1 ) O(1) O(1)
二分查找
看到要求的时间复杂度为O(logn)就想到二分法,但是二分查找只适用于有序数组,那这道题应该怎么做呢?
既然数组已经排序,那么原题可以表示成寻找target和第一个大于target的数的位置,利用二分查找进行。
为了复用二分查找函数,用一个equ参数表示找的是二者之中哪个数,为true,查找大于等于target的下标,否则查找大于target的下标。
最后,因为target可能不存在于数组中,因此还需要对返回的结果进行校验。
class Solution {
private int n;
public int[] searchRange(int[] nums, int target) {
n=nums.length;
int left=binarySearch(nums,target,true);
int right=binarySearch(nums,target,false)-1;
if(left<=right && right<n && nums[left]==target && nums[right]==target)
return new int[]{left,right};
return new int[]{-1,-1};
}
public int binarySearch(int[] nums,int target,boolean equ){
int l=0,r=n-1,res=n;
while(l<=r){
int mid=(l+r)/2;
if(nums[mid]>target||(equ&&nums[mid]>=target)){
r=mid-1;//mid右边肯定不是目标元素第一次出现的位置,继续往左边找
res=mid;
}
else
l=mid+1;
}
return res;
}
}
时间复杂度: O ( l o g n ) O(logn) O(logn)
空间复杂度: O ( 1 ) O(1) O(1)