【数据结构】01数组与字符串

一维数组

Q1:搜索插入位置

给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。

请必须使用时间复杂度为 O(log n) 的算法。

A1:暴力遍历

class Solution {
public:
    int searchInsert(vector<int>& nums, int target) {
        for(int i=0; i< nums.size(); i++){
            if(nums[i] == target){
                return i;
            } 
        }
        return nums.size() + 1;

    }
};

A2: 二分查找
思想:小于中间数,往左查;大于中间数,往右查。
查到最后left = right时,还未查到: 若小于该值,返回mid; 若大于该值,返回mid+1;

class Solution {
public:
    int searchInsert(vector<int>& nums, int target) {
        int left = 0;
        int right = nums.size() - 1;
        int mid=0;

        while(left <= right){
            mid = left + int((right - left + 1) /2);
            if(target == nums[mid] ){
                return mid;
            }
            else if(target > nums[mid]){
                left = mid+1;
            }
            else{
                right = mid -1;
            }
        }

        if(nums[mid] > target){
            return mid;
        }
        else{
            return mid +1;
        }

        return -1;

    }
};

Q2: 找数组中心索引

给你一个整数数组 nums ,请计算数组的 中心下标 。

数组 中心下标 是数组的一个下标,其左侧所有元素相加的和等于右侧所有元素相加的和。

如果中心下标位于数组最左端,那么左侧数之和视为 0 ,因为在下标的左侧不存在元素。这一点对于中心下标位于数组最右端同样适用。

如果数组有多个中心下标,应该返回 最靠近左边 的那一个。如果数组不存在中心下标,返回 -1 。

class Solution {
public:
    int pivotIndex(vector<int>& nums) {
        int sum = 0;
        int left=0, right=0;
        for(int i=0; i<nums.size();i++ ){
            sum += nums[i];
        }


        for(int i =0 ;i < nums.size(); i++){
        
           right = sum - left - nums[i];

           if(right==left){

               return i;
               
           }

           left += nums[i];

        }

        return -1;


    }
};

Q3: 合并区间

以数组 intervals 表示若干个区间的集合,其中单个区间为 intervals[i] = [starti, endi] 。请你合并所有重叠的区间,并返回 一个不重叠的区间数组,该数组需恰好覆盖输入中的所有区间 。
思想:

  1. 先将区间按照第一列从小到大排序
  2. 从第一行开始遍历: 若前end<后start, 不做合并; 若前end>=后start, 做合并
/**
 * Return an array of arrays of size *returnSize.
 * The sizes of the arrays are returned as *returnColumnSizes array.
 * Note: Both returned array and *columnSizes array must be malloced, assume caller calls free().
 */

int compare(const void* _a, const void * _b){
    int * a = * (int **)_a ;
    int * b = * (int **)_b ;
    return a[0] - b[0];
}
int** merge(int** intervals, int intervalsSize, int* intervalsColSize, int* returnSize, int** returnColumnSizes) {
    

    qsort(intervals, intervalsSize, sizeof(int *), compare );

    *returnSize = 0;

    int** result = (int **) malloc(sizeof(int *) * intervalsSize);
    for(int j =0; j< intervalsSize ; j++){
        result[j] = (int *) malloc(sizeof(int) * 2);
    }
    int * temp = (int *)malloc(sizeof(int) * 2);
    temp[0] = intervals[0][0];
    temp[1] = intervals[0][1];
    int i;
    for(i=1; i<intervalsSize; i++){
        //前end > 后start, {1,5} {3, 8} 需要合并 {1,8}
        if(temp[1]>= intervals[i][0]){
            temp[1] = fmax( intervals[i][1], temp[1]);

        }
        // {1,5} {7,9}
        else{
            
            result[*returnSize][0] = temp[0];
            result[*returnSize][1] = temp[1]; 
            temp[0] = intervals[i][0];
            temp[1] = intervals[i][1];

            *returnSize += 1;


        }


    }
    result[*returnSize][0] = temp[0];
    result[*returnSize][1] = temp[1]; 
    *returnSize += 1;

    *returnColumnSizes = (int*)malloc(sizeof(int)* (*returnSize));

    for(int j=0; j< *returnSize;j++){
        (*returnColumnSizes)[j] = 2;
    }

    return result;



    
}

二维数组

Q1:旋转矩阵

给你一幅由 N × N 矩阵表示的图像,其中每个像素的大小为 4 字节。请你设计一种算法,将图像旋转 90 度。

不占用额外内存空间能否做到?
给定 matrix =
[
[1,2,3],
[4,5,6],
[7,8,9]
],

原地旋转输入矩阵,使其变为:
[
[7,4,1],
[8,5,2],
[9,6,3]
]

思路:先沿对角线翻转,再水平翻转


void swap(int *a, int *b){
    int p;
    p = *a;
    *a = *b;
    *b = p;

}

void rotate(int** matrix, int matrixSize, int* matrixColSize){


    // 沿对角线旋转
    for(int i= 0; i< matrixSize; i++){
        for(int j =i ; j< matrixColSize[i]; j++){
            swap(&matrix[i][j], &matrix[j][i]);
        }
    }
    // 水平翻转
    for(int i= 0; i< matrixSize; i++){
        for(int j =0; j<(matrixColSize[i] / 2) ; j++){
            swap(&matrix[i][j], &matrix[i][matrixColSize[i]-1-j]);
        }
    }

}

Q2:对角线遍历

给你一个大小为 m x n 的矩阵 mat ,请以对角线遍历的顺序,用一个数组返回这个矩阵中的所有元素。

int* findDiagonalOrder(int** mat, int matSize, int* matColSize, int* returnSize) {
    int* result = (int*)malloc(sizeof(int) * (matSize * matColSize[0]));
    int i = 0, j = 1;
    int m = 1;
    int k = 0;
    result[0] = mat[0][0];
    if (matSize * matColSize[0] == 1){
        *returnSize = 1;

        return result;
    }
    if(matSize == 1){
        for(m = 1; m < matColSize[0] ; m++){
            result[m] = mat[0][m];
        }
        *returnSize = m;
        return result;
    }
    if(matColSize[0] == 1){
        for(m = 1; m < matSize; m++){
            result[m] = mat[m][0];
        }
        *returnSize = m;
        return result;
    }
    while ((i != matSize -1 ) || (j != returnSize[0] -1)) {

        /*result[m] = mat[i][j];
        printf("result[%d]: %d\n", m, result[m]);
        m++;*/
        result[m] = mat[i][j];
        //printf("result[%d]: %d  in i: %d, j: %d, k: %d\n", m, result[m], i, j, k);
        if (m == matSize * matColSize[0] -1 ) {
            break;
        } 

        if ((k % 2) == 0) {
            /*result[m] = mat[i][j];
            printf("result[%d]: %d  in i: %d, j: %d, k: %d\n", m, result[m], i, j, k);*/
            m++;
            i++;
            j--;
            /*result[m] = mat[i][j];
            printf("result[%d]: %d\n", m, result[m]);
            m++;*/
            if (j == 0 && i < matSize-1) {
                result[m] = mat[i][j];
                //printf("result[%d]: %d  in i: %d, j: %d, k: %d\n", m, result[m], i, j, k);
                m++;
                i++;
                k++;
                /*result[m] = mat[i][j];
                printf("result[%d]: %d\n", m, result[m]);
                m++;*/
            }
            else if ((i == matSize - 1)  && (j < matColSize[0] -1) ){
                result[m] = mat[i][j];
                //printf("result[%d]: %d  in i: %d, j: %d, k: %d\n", m, result[m], i, j, k);
                j++;
                m++;
                k++;
            }
            
            
        }
        else {
            /*result[m] = mat[i][j];
            printf("result[%d]: %d  in i: %d, j: %d, k: %d\n", m, result[m], i, j, k);*/
            m++;
            
            i--;
            j++;
            /*result[m] = mat[i][j];
            printf("result[%d]: %d\n", m, result[m]);
            m++;*/
            if (i == 0 && (j != matColSize[0] - 1) ){
                result[m] = mat[i][j];
                //printf("result[%d]: %d  in i: %d, j: %d, k: %d\n", m, result[m], i, j, k);
                m++;
                j++;
                k++;
                /*result[m] = mat[i][j];
                printf("result[%d]: %d\n", m, result[m]);
                m++;*/
            }
            else if (j == matColSize[0] - 1) {
                result[m] = mat[i][j];
                //printf("result[%d]: %d  in i: %d, j: %d, k: %d\n", m, result[m], i, j, k);
                i++;
                k++;
                m++;
            }
            
            
        }

    }
    *returnSize = m + 1;
    return result;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值