• 代码随想录 -- 双指针法


    移除元素

    题目链接

    描述

    给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。

    不要使用额外的数组空间,你必须仅使用 O(1) 额外空间原地修改输入数组。

    元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。

    示例 1: 给定 nums = [3,2,2,3], val = 3, 函数应该返回新的长度 2, 并且 nums 中的前两个元素均为 2。 你不需要考虑数组中超出新长度后面的元素。

    示例 2: 给定 nums = [0,1,2,2,3,0,4,2], val = 2, 函数应该返回新的长度 5, 并且 nums 中的前五个元素为 0, 1, 3, 0, 4。

    你不需要考虑数组中超出新长度后面的元素。

    题解:双指针法

    class Solution {
    public:
        int removeElement(vector<int>& nums, int val) {
            int len = nums.size();
            int slow{0};
            for(int fast=0;fast<len;++fast){
            	if(nums[fast]!=val)
            		nums[slow++]=nums[fast];
            }
            return slow;
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    题解:暴力

    双层循环即可

    反转字符串

    题目链接

    描述

    编写一个函数,其作用是将输入的字符串反转过来。输入字符串以字符数组 char[] 的形式给出。

    不要给另外的数组分配额外的空间,你必须原地修改输入数组、使用 O(1) 的额外空间解决这一问题。

    你可以假设数组中的所有字符都是 ASCII 码表中的可打印字符。

    示例 1:
    输入:[“h”,“e”,“l”,“l”,“o”]
    输出:[“o”,“l”,“l”,“e”,“h”]

    示例 2:
    输入:[“H”,“a”,“n”,“n”,“a”,“h”]
    输出:[“h”,“a”,“n”,“n”,“a”,“H”]

    题解

    class Solution {
    public:
    	void swap(char&c1,char&c2){
        	char tmp = c1;
        	c1=c2;
        	c2=tmp;
    	}
        void reverseString(vector<char>& s) {
        	size_t left = 0,right = s.size()-1;
    
        	while(left <right){
        		swap(s[left],s[right]);
        		++left;--right;
        	}
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    替换数字

    描述

    给定一个字符串 s,它包含小写字母和数字字符,请编写一个函数,将字符串中的字母字符保持不变,而将每个数字字符替换为number。

    例如,对于输入字符串 “a1b2c3”,函数应该将其转换为 “anumberbnumbercnumber”。

    对于输入字符串 “a5b”,函数应该将其转换为 “anumberb”

    输入:一个字符串 s,s 仅包含小写字母和数字字符。

    输出:打印一个新的字符串,其中每个数字字符都被替换为了number

    样例输入:a1b2c3

    样例输出:anumberbnumbercnumber

    数据范围:1 <= s.length < 10000。

    题解

    #include 
    #include 
    using namespace std;
    
    void change_string(string&s){
    	size_t old_len = s.size();
    	int count{0};
    	for(int i=0;i<old_len;++i){
    		if(s[i]<='9'&&s[i]>='0')
    			++count;
    	}
    	s.resize(old_len+5*count);
    	size_t new_len = s.size();
    	for(int front = old_len-1,back=new_len-1;front>=0;--back,--front){
    		if(s[front]>='0'&&s[front]<='9'){
    			s[back]='r';
    			s[back-1]='e';
    			s[back-2]='b';
    			s[back-3]='m';
    			s[back-4]='u';
    			s[back-5]='n';
    			back-=5;
    		}else
    			s[back]=s[front];
    	}
    }
    int main(){
    	string s;
    	cin>>s;
    	change_string(s);
    	cout<<s<<"\n";
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33

    翻转字符串里的单词

    题目链接

    描述

    示例 1:
    输入: “the sky is blue”
    输出: “blue is sky the”

    示例 2:
    输入: " hello world! "
    输出: “world! hello”
    解释: 输入字符串可以在前面或者后面包含多余的空格,但是反转后的字符不能包括。

    示例 3:
    输入: “a good example”
    输出: “example good a”
    解释: 如果两个单词间有多余的空格,将反转后单词间的空格减少到只含一个。

    题解

    class Solution {
    public:
    	void deleteExtSpace(string&s){
    		int slow{0},fast{0};
    		size_t len{s.size()};
    		while(fast<len&&s[fast]==' ')
    			++fast;
    		while(fast<len){
    			if(fast>0&&s[fast]==' '&&s[fast-1]==' '){
    				++fast;continue;
    			}else{
    				s[slow++]=s[fast++];
    			}
    		}
    		if(slow-1>0&&s[slow-1]==' '){
    			s.resize(slow-1);
    		}else
    			s.resize(slow);
    	}
    	void reverseStr(string&s,int beg,int end){
    		if(end<beg)return;
    		while(beg<end){
    			char tmp = s[beg];
    			s[beg]=s[end];
    			s[end]=tmp;
    			++beg;
    			--end;
    		}
    	}
        string reverseWords(string&s){
        	deleteExtSpace(s);
        	reverseStr(s,0,s.size()-1);
        	int i,j;
        	for(i=0,j=0;i<s.size();++i){
        		if(s[i]==' '){
        			reverseStr(s,j,i-1);
        			j=i+1;
        		}
        	}
        	reverseStr(s,j,i-1);
        	return s;
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43

    反转链表

    题目链接

    class Solution {
    public:
        ListNode *reverseList(ListNode *head) {
        	if(!(head&&head->next))return head;
        	ListNode*pre = nullptr,*cur=head;
        	while(cur){
        		ListNode*tmp = cur->next;
        		cur->next = pre;
        		pre = cur;
        		cur = tmp;
        	}
        	return pre;
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    删除链表的倒数第N个节点

    题目链接

    class Solution {
    public:
        ListNode* removeNthFromEnd(ListNode* head, int n) {
            ListNode*fhead = new ListNode(0,head);
        	ListNode*slow = fhead,*fast = fhead;
        	while(n--)
        		fast = fast->next;
        	while(fast->next){
        		slow=slow->next;
        		fast=fast->next;
        	}
        	slow->next = slow->next->next;
        	return fhead->next;
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    链表相交

    题目链接

    
    class Solution {
    public:
        ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
            size_t lA{0},lB{0};
            ListNode*a = headA;
            while (a){
                lA++;
                a=a->next;
            }
            ListNode*b = headB;
            while (b){
                lB++;
                b=b->next;
            }
            //a 短  b长
            a=lA>lB?headB:headA;
            b=lA>lB?headA:headB;
            size_t len = lA>lB?lA-lB:lB-lA;
            while (len--)
                b=b->next;
            while (a&&b){
                if(a==b)
                    return a;
                a=a->next;
                b=b->next;
            }
            return nullptr;
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    环形链表II

    题目链接

    class Solution {
    public:
        ListNode* detectCycle(ListNode *head) {
            ListNode*slow=head,*fast=head;
            while (fast && fast->next){
                slow=slow->next;
                fast=fast->next->next;
                if(slow==fast){
                   //存在环
                   slow = head;
                    while (slow!=fast){
                        fast=fast->next;
                        slow=slow->next;
                    }
                    return slow;
                }
            }
            return nullptr;
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    三数之和

    题目链接

    class Solution {
    public:
        vector<vector<int>> threeSum(vector<int> &nums) {
            vector<vector<int>> result;
            sort(nums.begin(), nums.end());
            size_t len = nums.size();
            for (int i = 0; i < len; ++i) {
                if (nums[i] > 0)break;
                //去重i
                if (i > 0 && nums[i] == nums[i - 1])continue;
                int slow = i + 1, fast = len - 1;
                while (slow < fast) {
                    if (nums[i] + nums[slow] + nums[fast] > 0)
                        --fast;
                    else if (nums[i] + nums[slow] + nums[fast] < 0)
                        ++slow;
                        //nums[i]+nums[slow]+nums[fast] == 0  还要考虑对slow fast去重
                    else {
                        result.push_back(vector<int>{nums[i], nums[slow], nums[fast]});
    
                        //有重复 进行移位
                        // fast是和前一位比较 如果相同可以用前一位替换
                        // slow是和后一位比较 如果相同可以用后一位替换
                        while (slow < fast && nums[slow] == nums[slow + 1])
                            ++slow;
                        while (slow < fast && nums[fast] == nums[fast - 1])
                            --fast;
    
                        //fast slow没有重复也要位移
                        ++slow;
                        --fast;
                    }
                }
            }
            return result;
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37

    四数之和

    题目链接

    class Solution {
    public:
        vector<vector<int>> fourSum(vector<int> &nums, int target) {
            vector<vector<int>> result;
            sort(nums.begin(), nums.end());
            int len = nums.size();
            for (int i = 0; i < len; ++i) {
                if (nums[i] > target && nums[i] >= 0)break;
                //去重第一个
                if (i > 0 && nums[i] == nums[i - 1])continue;
    
                //下面和复现三数之和
                for (int j = i + 1; j < len; ++j) {
                    int tmp = nums[i] + nums[j];
                    if (tmp >= 0 && tmp > target)break;
                    if (j > i + 1 && nums[j] == nums[j - 1])continue;
    
                    int left = j + 1, right = len - 1;
                    while (left < right) {
                        if ((long) tmp + nums[left] + nums[right] > target)
                            --right;
                        else if ((long) tmp + nums[left] + nums[right] < target)
                            ++left;
                        else {
                            //相等 但是对left和right去重
                            result.push_back(vector<int>{nums[i], nums[j], nums[left], nums[right]});
                            while (left < right && nums[left] == nums[left + 1])++left;
                            while (left < right && nums[right] == nums[right - 1])--right;
    
                            //正常的移动
                            ++left;
                            --right;
                        }
                    }
                }
            }
            return result;
        }
    };
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
  • 相关阅读:
    istio学习(2)bookinfo示例
    CocosCreator 面试题(十一)Cocos Creator 屏幕适配
    [数据集][目标检测]航空发动机缺陷检测数据集VOC+YOLO格式291张4类别
    企业级信息化系统 ERP、OA、CRM、EAM、WMS、MES、PM
    通过Linux命令监控CPU案例
    Ruby语言介绍要点难点代码案例参考实际应用举例
    UDP通信程序的详细解析
    模拟电路设计(34)---脉宽调制型开关电路
    Django ORM
    复数类。。
  • 原文地址:https://blog.csdn.net/bossDDYY/article/details/136272967