学习内容:https://blog.csdn.net/WhereIsHeroFrom/article/details/121551694
一、今日知识点总结
-
概念
-
指针 == 地址
-
数据放置在内存中,占用不同大小的字节
数据类型 占用字节数 32位整型 int
4 64位整型 long long
8 字符型 char
1 -
每个字节都有唯一编号 称之为 地址 or 指针
-
指针变量 ==> 存放指针的变量
DataType *var; //指向什么类型的变量,DataType就是什么数据类型 // 如 char x = '0'; char *p = &x; //0xCF - & ==> 取地址符号 int k = 10; int *p = &k; int z = *p; //解引用,对指针变量p,用*即可获得该地址对应的内存存储的值 int a[] = {1,2,5,5,6}; int *p = a; //对于数组变量,不需要用&取地址符,数组的地址是连续的。a是数组的第一个元素地址,p等于a即可。
-
内存申请:
//p代表申请了一段内存,有效内存字节数=1024字节 int *p = (int *)malloc(1024); //对于数组的申请: 申请长度为n的int型数组 int *p1 = (int *)malloc( sizeof(int) * n)
-
范式:返回数组
//... int a[7] = {3,41,5123,121,12}; int rSize; int * ret = getList(a,7,&rSize); //... int *getList(int *nums, int numsSize; int *returnSize ){ //申请一块自定义大小的内存,作为数组使用 int *ret = (int *)malloc( sizeof(int) * xxx); //TODO //... //通过参数返回值 *returnSize = xxx; //解引用,把返回的数组长度传给调用方的rSize,调用方即可知道新数组的长度了。 return ret;//返回申请的数组内存的数组首地址 }
-
二、今日解题
战绩:
解题1:重新排列数组
//思路1
int* shuffle(int* nums, int numsSize, int n, int* returnSize){
int *ans = (int *)malloc(sizeof(int)*numsSize);
for(int i=0;i<numsSize;i++){
if(i&1){
//奇数
ans[i] = nums[i/2+n];
}else{
//偶数
ans[i] = nums[i/2];
}
}
*returnSize = numsSize;
return ans;
}
//思路2 **
int* shuffle(int* nums, int numsSize, int n, int* returnSize){
int *ret = (int *)malloc( sizeof(int) * numsSize );
for(int i = 0;i<n;i++){
ret[2*i] = nums[i];
ret[2*i+1] = nums[n+i];
}
*returnSize = numsSize;
return ret;
}
解题2:数组串联
/**
* Note: The returned array must be malloced, assume caller calls free().
*/
int* getConcatenation(int* nums, int numsSize, int* returnSize){
int * ret = (int *)malloc(sizeof(int)*2*numsSize);
*returnSize = 2*numsSize;
for(int i = 0;i<numsSize;i++){
ret[i] = nums[i];
ret[i+numsSize] = nums[i];
}
return ret;
}
解题3: 基于排列构建数组
/**
* Note: The returned array must be malloced, assume caller calls free().
*/
int* buildArray(int* nums, int numsSize, int* returnSize){
int *ret = (int *)malloc( sizeof(int) * numsSize);
*returnSize = numsSize;
for(int i = 0; i < numsSize; ++i){
ret[i] = nums[nums[i]];
}
return ret;
}
解题4:一维数组的动态和
/**
* Note: The returned array must be malloced, assume caller calls free().
*/
int* runningSum(int* nums, int numsSize, int* returnSize){
int *ret = (int *)malloc( sizeof(int) * numsSize);
for(int i = 0;i<numsSize;++i){
ret[i] = 0;
for(int j = 0;j<=i;j++){
ret[i] += nums[j];
}
}
*returnSize = numsSize;
return ret;
}
解题5:左旋转字符串
char* reverseLeftWords(char* s, int n){
int l = strlen(s);
char *ans = (char *)malloc(sizeof(char)*(l+1));
for(int i = 0;i<l;i++){
if(i<l-n){
ans[i] = s[n+i];
}else{
ans[i] = s[i+n-l];
}
}
ans[l] = '\0';调用者就可以通过strlen来获知字符串长度了. 相当于 *rSize = len;
return ans;
}
解题思路
根据题目要求,可以得到如下对应关系:
则可以得知:
当 i = [0, len-n-1]时,ans[i] = s[n+i];
当 i = [len - n, len - 1]; ans[i] = s[i-len+n]
1108. IP 地址无效化
char * defangIPaddr(char * address){
int n = strlen(address);
char *ans = (char *)malloc(sizeof(char)*(n+7)); //重点:长度的计算,长度增加3个[] + 一位结束位
int returnSize = 0;
for(int i = 0;i<n;i++){
if(address[i] == '.'){
ans[returnSize++]='[';//通过rSize自增的方式来作为新字符串的下标索引
ans[returnSize++]='.';
ans[returnSize++]=']';
}else{
ans[returnSize++]=address[i];
}
}
ans[returnSize] = '\0';//
return ans;
}
剑指 Offer 05. 替换空格
char* replaceSpace(char* s){
int n = strlen(s);
char *ans = (char *)malloc(sizeof(char)*(3*n+1)); //也是对长度计算的确定,一个空格=3,假设全为空格,最后加一个结束位。
int i;
int returnSize = 0;
for( i = 0;i<n;i++){
if(s[i]==' '){
ans[returnSize++] = '%';
ans[returnSize++] = '2';
ans[returnSize++] = '0';
}else{
ans[returnSize++] = s[i];
}
}
ans[returnSize] = '\0';
return ans;
}
1365. 有多少小于当前数字的数字
/**
* Note: The returned array must be malloced, assume caller calls free().
*/
int* smallerNumbersThanCurrent(int* nums, int numsSize, int* returnSize){
//每个数的计数器,通过一个数组结构来记录,每个元素,就是对应数组小标元素的小于的计数
int *ans = (int *)malloc(sizeof(int)*numsSize);
//遍历数组,取得每一个数
for(int i = 0;i<numsSize;i++){
ans[i] = 0;
//再遍历一遍数组,对比和当前数的大小,若比当前数小,则给当前数的计数器+1
for(int j = 0;j<numsSize;j++){
if(nums[i]>nums[j]){
ans[i]++;
}
}
}
*returnSize = numsSize;
return ans;
}
剑指 Offer 17. 打印从1到最大的n位数
/**
* Note: The returned array must be malloced, assume caller calls free().
*/
int* printNumbers(int n, int* returnSize){
//计算出最大n位数 == n个10相乘 - 1;
int l = 1;
for(;n>0;n--){
l *= 10;
}
l--;
int *ans = (int *)malloc(sizeof(int)*l);
//从1开始打
for(int i =1;i<=l;i++){
//下标要退一位,否则首位未赋值,且最后溢出
ans[i-1] = i;
}
*returnSize = l;
return ans;
}
1389. 按既定顺序创建目标数组
/**
* Note: The returned array must be malloced, assume caller calls free().
*/
int* createTargetArray(int* nums, int numsSize, int* index, int indexSize, int* returnSize){
int * ans = (int *)malloc(sizeof(int)*numsSize);
/**
* 重点在于理解题目的要求是,在下标=index[i]处插入,既然是插入,则涉及到当前原有的数及后续的数都要右移
*/
int i,j,ins,idx;
int len = 0;
for( i =0;i<numsSize;i++){
idx = index[i];
ins = nums[i];
//插入 - 后移一位 (从末尾开始右移一位)
for(j=len;j>idx;j--){
ans[j] = ans[j-1];
}
ans[idx] = ins;
len++;
}
*returnSize = len;
return ans;
}