《九日集训》第十五轮 (第四讲) 指针

知识点

指针

/**
 * Note: The returned array must be malloced, assume caller calls free().  // (1)
 */
 int *func(int *nums, int numsSize, int *returnSize) {                     // (2)
     int *ret = (int *)malloc( sizeof(int) * xxx );                        // (3)
     // TODO                                                               // (4)
     *returnSize = xxx;                                                    // (5)
     return ret;                                                           // (6)
 }

题目分析

题目1

1470. 重新排列数组

分析

可以知道\(y_n=x_n+n\),所以开一个数组,从\(0\)开始遍历到\(n-1\),然后将原数组的元素分两次放入结果数组中就行了

代码

class Solution {
public:
    vector<int> shuffle(vector<int>& nums, int n) {
        vector<int>result;

        for(int i=0;i<n;i++){
            result.push_back(nums[i]);
            result.push_back(nums[i+n]); 
        }
        return result;
    }
};

题目2

1929. 数组串联

分析

简单的遍历

代码

class Solution {
public:
    vector<int> getConcatenation(vector<int>& nums) {
        vector<int>res;
        for(int i=0;i<nums.size()*2;i++){
            i<nums.size()?res.push_back(nums[i]):res.push_back(nums[i-nums.size()]);
        }
        return res;
    }
};

题目3

1920. 基于排列构建数组

分析

简单遍历

代码

class Solution {
public:
    vector<int> buildArray(vector<int>& nums) {
        vector<int>res;
        for(int i=0;i<nums.size();i++){
            res.push_back(nums[nums[i]]);
        }
        return res;
    }
};

题目4

1480. 一维数组的动态和

分析

一维前缀和

\[\because \quad S[i] = a[1] + a[2] + ... a[i]\\ \quad\quad\therefore \quad a[l] + ... + a[r] = S[r] - S[l - 1] \]

代码

class Solution {
public:
    vector<int> runningSum(vector<int>& nums) {
        int s[nums.size()+1];
        vector<int> sum;
        for(int i=1;i<=nums.size();i++){
            s[i]=s[i-1]+nums[i-1];
            sum.push_back(s[i]-s[0]);
        }

        return sum;
    }
};

题目5

剑指 Offer 58 - II. 左旋转字符串

分析

代码随想录刷过这题qwq,反转字符串,一共反转三次。第一次先反转\([0,n-1]\)范围内的字符串,第二次反转\([n-1,n]\)内的字符串,第三次把整个字符串反转一下。

\(abcdefg,k=2\)

第一次反转:\(bacdefg\)

第二次反转:\(bagfedc\)

第三次反转:\(cdefgab\)

代码

class Solution {
public:
    void reverse(string&s,int start,int end){
        for(int i=start,j=end;i<j;i++,j--){
            swap(s[i],s[j]);
        }
    }

    string reverseLeftWords(string s, int n) {
        reverse(s,0,n-1);
        reverse(s,n,s.size()-1);
        reverse(s,0,s.size()-1);
        return s;
    }
};

题目6

1108. IP 地址无效化

分析

代码随想录刷过类似的替换空格,思路差不多

  1. 扩充数组到每个空格替换成"[.]"之后的大小。
  2. 然后从后向前替换空格,也就是双指针法,过程如下:
  3. i指向新长度的末尾,j指向旧长度的末尾。

答案

class Solution {
public:
    string defangIPaddr(string address) {
        int count=0;//统计'.'的个数
        int OldSize=address.size();
        for(int i=0;i<address.size();i++)
            if(address[i]=='.')count++;
        
        //扩充字符串的大小,将每个空格替换成'[.]'之后的大小
        address.resize(address.size()+count*2);
        int NewSize=address.size();
        //从后往前将'.'替换成'[.]'
        for(int i=NewSize-1,j=OldSize-1;j<i;i--,j--){
            if(address[j]!='.')address[i]=address[j];
            else{
                address[i]=']';
                address[i-1]='.';
                address[i-2]='[';
                i-=2;
            }
        }
        return address;
    }
};

题目7

剑指 Offer 05. 替换空格

分析

上题刚说完它就来了qwq

代码

class Solution {
public:
    string replaceSpace(string s) {
        int count=0;
        int sOldSize=s.size();
        for(int i=0;i<s.size();i++)
            if(s[i]==' ')count++;
        
        s.resize(s.size()+count*2);
        int sNewSize=s.size();
        for(int i=sNewSize-1,j=sOldSize-1;j<i;i--,j--){
            if(s[j]!=' ')s[i]=s[j];
            else{
                s[i]='0';
                s[i-1]='2';
                s[i-2]='%';
                i-=2;
            }
        }
        return s;
    }
};

题目8

1365. 有多少小于当前数字的数字

分析

\(sort\)一下,然后数组的下标就是数组中比它小的所有数字的数量,因为有重复元素,所以取最小的那个下标,选择从后往前遍历

代码

class Solution {
public:
    vector<int> smallerNumbersThanCurrent(vector<int>& nums) {
        vector<int> temps(nums.begin(),nums.end()),res;
        sort(temps.begin(),temps.end());

        int temp[110];
        for(int i=nums.size()-1;i>=0;i--){
            temp[temps[i]]=i;
        }
        for(int i=0;i<nums.size();i++)res.push_back(temp[nums[i]]);
        return res;
    }
};

题目9

剑指 Offer 17. 打印从1到最大的n位数

分析

如果不考虑大数的话,一个for循环遍历到最大数即可(不考虑大数居然也能过,白写了那么久的代码,淦),考虑大数的话,定义一个字符串,对每位进行0-9的枚举,最后去掉数字前面的0即可。

代码

考虑溢出版
#include<string>
#include<iostream>
#include<algorithm>
#include<vector>

const int N = 16;


using namespace std;
int res[N];

int n;

void dfs(int u) {
	if (u > n) {
		string s;
		for (int i = 1; i <= n; i++) {
			s=s+to_string(res[i]);
		}

        //去掉数字前面的0
		while (true) {
			if (s[0] != '0') {
				break;
			}
			else {
				s.erase(0, 1);
			}
		}
		if (s != "")cout<<s<<endl;

		return; 
	}
    
    //暴力枚举每位的数
	for (int i = 0; i <= 9; i++) { 
		res[u] = i; 
		dfs(u + 1);
	}
}

int main() {
	cin >> n;
	dfs(1);
}
不考虑溢出版
class Solution {
public:
    vector<int> printNumbers(int n) {
        vector<int>v;
        for(int i=1;i<pow(10,n);i++)
        v.push_back(i);
        return v;
    }
};

题目10

1389. 按既定顺序创建目标数组

分析

这题是在指定位置插入数据,最快的应该是单链表了吧qwq

代码

struct LinkList{
        int val;
        LinkList* next;
        LinkList(int val):val(val),next(nullptr){}

        void index(int index,int val){
            LinkList*cur=this;
            LinkList*newNode=new LinkList(val);
            while(index--){
                cur=cur->next;
            }
            newNode->next=cur->next;
            cur->next=newNode;
    }
};



class Solution {
public:
    vector<int> createTargetArray(vector<int>& nums, vector<int>& index) {
        LinkList*p =new LinkList(0);
        vector<int> result;
        for(int i=0;i<nums.size();i++){
            p->index(index[i],nums[i]);
        }

        p=p->next;
        while(p){
            result.push_back(p->val);
            p=p->next;
        }

        return result;
    }
};

总结

今天好多以前做过的题目qwq
image

posted @ 2022-03-31 23:09  灰之魔女伊蕾娜  阅读(55)  评论(0)    收藏  举报