求最小K个数、进制转换、三数之和、iou计算

 1、求最小K个数(设计一个算法,找出数组中最小的k个数。以任意顺序返回这k个数均可。)

设计一个算法,找出数组中最小的k个数。以任意顺序返回这k个数均可。

示例:

        输入: arr = [1,3,5,7,2,4,6,8], k = 4
        输出: [1,2,3,4]

提示:

        0 <= len(arr) <= 100000
        0 <= k <= min(100000, len(arr))

一开始想到的方法是直接排序后,返回前k个值,采用了冒泡排序,但是这种方法超出了时间限制。

C语言实现代码如下(采用冒泡排序):

/**
 * Note: The returned array must be malloced, assume caller calls free().
 */
int* smallestK(int* arr, int arrSize, int k, int* returnSize){
    int i,j,t;
    for(i=0;i<arrSize;i++){
        for(j=0;j<arrSize-i-1;j++){
            if(arr[j]>arr[j+1]){
                t=arr[j];
                arr[j]=arr[j+1];
                arr[j+1]=t;
            }
        }
    }
    *returnSize=k;//给指针指向的内容赋值
    //printf("%d",*returnSize);//读取指针指向的内容
    return arr;
}

于是想到要降低时间开销,采用了时间复杂度较低 Ο(nlogn)的快速排序,快速排序每次可以返回所选基准数的位置(用p表示):

  • ①、如果p=k-1,则所求数全部在该基准数位置左侧加上该基准数,不再递归调用排序。
  • ②、如果p<k-1,则所求数包括该基准数位置左侧全部数、该基准数位置右侧部分数,在右侧递归调用排序方法进行排序。
  • ③、如果p>k-1,则所求数为左侧部分数,在左侧递归调用排序方法进行排序。

C语言实现代码如下(采用快速排序): 

/**
 * Note: The returned array must be malloced, assume caller calls free().
 */
int getindex(int* arr,int low,int high){
    int t=arr[low];
    while(low<high){
        while(low<high&&arr[high]>=t){
            high--;
        }
        arr[low]=arr[high];
        while(low<high&&arr[low]<=t){
            low++;
        }
        arr[high]=arr[low];
    }
    arr[low]=t;
    return low;
}
void quicksort(int* arr,int low,int high,int k){
    int index;
    if(low<high){
        index=getindex(arr,low,high);
        if(k-1>index){
            quicksort(arr,index+1,high,k);
        }else if(k-1<index){
            quicksort(arr,low,index-1,k);
        }
    }
}
int* smallestK(int* arr, int arrSize, int k, int* returnSize){
    int i;
    quicksort(arr,0,arrSize-1,k);
    for(i=0;i<k;i++){
        printf("%d\t",arr[i]);
    }
    *returnSize=k;//给指针指向的内容赋值
    //printf("%d",*returnSize);//读取指针指向的内容
    return arr;
}

2、二进制转十进制,十六进制转二进制

python实现代码如下:

def base_conversion(value, mode):
   result=0
   if mode=="bin2dec": #二进制转十进制
       vlength=len(value)
       for i in range(vlength-1,-1,-1):
           result=result+int(value[i])*(2**(vlength-1-i))
       return result
   else:#十六进制转二进制
       vlength = len(value)
       rs=''
       for i in range(vlength):
           if value[i]=='A':
               rs=rs+'1010'
           elif value[i] == 'B':
               rs = rs + '1011'
           elif value[i] == 'C':
               rs = rs + '1100'
           elif value[i]=='D':
               rs=rs+'1101'
           elif value[i]=='E':
               rs=rs+'1110'
           elif value[i]=='F':
               rs=rs+'1111'
           else:
               for a in range(2):
                   for b in range(2):
                       for c in range(2):
                           for d in range(2):
                               if a*8+b*4+c*2+d*1==int(value[i]):
                                   rs=rs+str(a)+str(b)+str(c)+str(d)
                                   break
   return  int(rs)
print(base_conversion("7A98","dec2bin"))

3、三数之和

给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?请你找出所有和为 0 且不重复的三元组。

注意:答案中不可以包含重复的三元组。

示例 1:

输入:nums = [-1,0,1,2,-1,-4]
输出:[[-1,-1,2],[-1,0,1]]

示例 2:

输入:nums = []
输出:[]

示例 3:

输入:nums = [0]
输出:[]

int** threeSum(int* nums, int numsSize, int* returnSize, int** returnColumnSizes)。这里我有一个问题,根据note,我搞不懂** returnColumnSizes的作用是什么?我以为是用来返回最终的二维数组,因此的我代码如下,且本地编译没有问题,但是上传到平台提交就报错。

C语言实现代码如下:

#include <stdio.h>
#include <stdlib.h>
int** threeSum(int* nums, int numsSize, int* returnSize, int** returnColumnSizes);

int main(){
    int nums[]={-1,0,1,2,-1,-4},i,j;
    int numSize=6,rsSize=0;
    int *rs=&rsSize;
    int** returnColumnSizes;
    returnColumnSizes=threeSum(nums,6,rs,returnColumnSizes);//可以直接返回二维数组
    printf("rs:%d\n",*rs);
    for(j=0;j<rsSize;j++){
        for(i=0;i<3;i++){
            printf("%d\t",returnColumnSizes[j][i]);
        }
        printf("\n");
    }
}
int** threeSum(int* nums, int numsSize, int* returnSize, int** returnColumnSizes){
    int i,j,k,t;
    int flag;
    if(numsSize<3){
        return NULL;
    }
    //先将数组排序,冒泡排序
    for(i=0;i<numsSize;i++){
        for(j=0;j<numsSize-i-1;j++){
            if(nums[j]>nums[j+1]){
                t=nums[j];
                nums[j]=nums[j+1];
                nums[j+1]=t;
            }
        }
    }
    // for(i=0;i<numsSize;i++){
    //     printf("nums:%d\n",nums[i]);
    // }
    //初始化二维数组
    returnColumnSizes=(int **)malloc(numsSize*sizeof(int*));
    for(j=0;j<numsSize;j++){
        returnColumnSizes[j]=(int *)malloc(3*sizeof(int));
    }
    //遍历进行判断
    for(i=0;i<numsSize;i++){
        j=i+1;k=numsSize-1;
        while(j<k){
            //printf("%d-%d",j,k);
            if(nums[i]+nums[j]+nums[k]==0){
                flag=0;
                for(t=0;t<*returnSize;t++){//遍历判断是否重复
                    if(returnColumnSizes[t][0]==nums[i]&&returnColumnSizes[t][1]==nums[j]
                    &&returnColumnSizes[t][2]==nums[k]){
                        flag=1;
                        break;
                    }
                }
                if(flag==0){
                    returnColumnSizes[*returnSize][0]=nums[i];
                    returnColumnSizes[*returnSize][1]=nums[j];
                    returnColumnSizes[*returnSize][2]=nums[k];
                    *returnSize=*returnSize+1;
                }
                --k;
            }else if(nums[i]+nums[j]+nums[k]>0){
                --k;
            }else{
                ++j;
            }            
        }       
    }
    //*returnSize=55;
    printf("returnSize:%d\n",*returnSize);
    return returnColumnSizes;
}

4、IOU的计算

def ioucompute(BoxA,BoxB):
    x1min,y1min,x1max,y1max=BoxA
    x2min,y2min,x2max,y2max=BoxB
    allarea=(y1max-y1min)*(x1max-x1min)+(y2max-y2min)*(x2max-x2min)
    xa=max(x1min,x2min)
    ya=max(y1min,y2min)
    xb=min(x1max,x1max)
    yb=min(y1max,y2max)
    inter=max(0,xb-xa+1)*max(0,yb-ya+1)
    iou=inter/(allarea-inter)
    print(iou)

boxA = [0,0,5,5]
boxB = [1,1,6,6]
ioucompute(boxA,boxB)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值