1. 程式人生 > 其它 >[學習報告]《九日集訓》第十五輪 (第四講) 指標

[學習報告]《九日集訓》第十五輪 (第四講) 指標

知識點

指標

/**
 * 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;
    }
};