算法日志3:线性表神人

前言

数组&链表常见题


数组

移除数组元素

7. 移除元素

给你一个数组 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。

你不需要考虑数组中超出新长度后面的元素。
  1. 两层循环

c++

class Solution {
public:
    int removeElement(vector<int>& nums, int val) {
        int len = nums.size();
        for(int i =0; i< len;i++){
            if(nums[i]==val){
                for(int j = i; j<len-1;j++){
                    nums[j] = nums[j+1];

                }
                i-=1;
                len-=1;
            }
        }
        return len;
    }
};

注意python3中的 range相当于python2中的xrange, 返回了一个类似生成器的对象,但它并不是一个真正的生成器,而是一个不可变的序列类型。这意味着你不能直接对range()对象进行修改(如添加或删除元素),它们主要用于遍历一系列值,特别是在for循环中。

尽管range()对象在内存使用方面非常高效,因为它只在需要时计算值(懒加载),但它的内容是固定的,一旦创建就不能更改。这与列表不同,列表是可变的,允许你添加、删除和修改其中的元素

python

class Solution:
    def removeElement(self, nums: List[int], val: int) -> int:
        mylen=len(nums)
        i = 0
        while i < mylen:

            if nums[i] == val:
                for j in range(i,mylen-1):
                    nums[j] = nums[j+1]
                i-=1
                mylen-=1
            i+=1
        return mylen
  1. 双指针法

c++

class Solution {
public:
    int removeElement(vector<int>& nums, int val) {
        int p1 =0,p2=0;
        int len = nums.size();
        while(1){
            if(p1 == len) break;
            if(nums[p1] != val){
                nums[p2] = nums[p1];
                ++p1;
                ++p2;
            }
            else if(nums[p1] == val){
                ++p1;
            }
        }
        return p2;
    }
};

python

class Solution:
    def removeElement(self, nums: List[int], val: int) -> int:
        p1,p2 = 0,0
        mylen = len(nums)
        while 1:
            if p1 == len(nums):
                break
            if nums[p1] != val:
                nums[p2] = nums[p1]
                p1+=1
                p2+=1
            elif nums[p1] == val:
                p1+=1
        return p2
            s

删除排序数组中的重复项

c++

class Solution {
public:
    int removeDuplicates(vector<int>& nums) {
        int p2 = 0;
        int len = nums.size();
        for(int p1 = 0 ; p1<len;p1++){
            if(nums[p1] != nums[p2]){
                nums[++p2] = nums[p1];
            }
        }
        return p2+1;


    }
};

有序数组的平方

c++

class Solution {
public:
    vector<int> sortedSquares(vector<int>& nums) {
        int len = nums.size();
        vector<int> res(len);
        int p1=0,p2=len-1,pr=len-1;
        while(p1<=p2){
            if(nums[p1]*nums[p1]>nums[p2]*nums[p2]){
                res[pr] = nums[p1]*nums[p1];
                pr--;
                p1++;  
            }
            else{
                res[pr] = nums[p2]*nums[p2];
                pr--;
                p2--;
            }
        }
        return res;

    }
};

长度最小的子数组

class Solution {
    public:
        int minSubArrayLen(int target, vector<int>& nums) {
            int p1= 0,p2 =0;
            int len = nums.size();
            int cnt = len+1;
            int sum = 0;
            for(p2 = 0; p2<len;p2++){
                sum += nums[p2];
                while(sum>=target && p1<=p2){
                    // cout<<p1<<" "<<p2<<endl;
                    if(cnt > p2-p1+1) {
                        cnt = p2-p1+1;
                    }
                    sum -= nums[p1++];
                }
            }
            cnt = cnt == len+1 ?0 :cnt;
        return cnt;
        }
};

区间和

#include<iostream>
#include<vector>
using namespace std;
int main(){
    int n;
    cin>>n;
    vector<int> arr(n);
    int i = 1;
    cin>>arr[0];
    n--;
    int tmp;
    while(n--){
        cin>>tmp;
        arr[i] = arr[i-1]+tmp;
        i++;
    }
    int l,r;
    while(cin>>l>>r){
        // cout<<l<<" "<<r<<endl;
        if(l>0){
            cout<<arr[r]-arr[l-1]<<endl;
        }
        else{
            cout<<arr[r]<<endl;
        }

    }

}

开发商选土地

#include<iostream>
#include<vector>
using namespace std;
int main(){
    int n,m;
    cin>>n>>m;
    vector<vector<int>> arr(n, vector<int>(m,0));


    for(int i =0;i<n;i++){
        for(int j =0; j<m;j++){
            cin>>arr[i][j]; 
        }
    }

    vector<int> arr_row(m,0);
    vector<int> arr_col(n,0);
    vector<int> arr_row_sum(m,0);
    vector<int> arr_col_sum(n,0);

    for(int i =0; i<m;i++){
        for(int j =0; j<n;j++){
            arr_row[i]+=arr[j][i];
        } 
    }


    for(int i =0; i<n;i++){
        for(int j =0; j<m;j++){
            arr_col[i]+=arr[i][j];
        }
    }

    arr_row_sum[0] = arr_row[0];
    for(int i = 1; i<m ;i++){
        arr_row_sum[i] = arr_row[i]+arr_row_sum[i-1];
    }
    // //测试arr_row 和 arr_row_sum
    
    // for(int i = 0; i< m;i++){
    //     cout<<arr_row[i]<<" "<<arr_row_sum[i]<<endl;
    // }
    // //
    

    arr_col_sum[0] = arr_col[0];
    for(int i = 1; i<n ;i++){
        arr_col_sum[i] = arr_col[i]+arr_col_sum[i-1];
    }

    // //测试arr_row 和 arr_row_sum
    // for(int i = 0; i< n;i++){
    //     cout<<arr_col[i]<<" "<<arr_col_sum[i]<<endl;
    // }
    // //

    int min_row = INT32_MAX;
    int tmp = 0;
    for(int i =0; i<m;i++){
        tmp = arr_row_sum[i] - (arr_row_sum[m-1] - arr_row_sum[i]);
        tmp = tmp>0?tmp:-tmp;
        if(min_row > tmp) min_row = tmp;
    }

    



    int min_col = INT32_MAX;
    tmp = 0;
    for(int i =1; i<n;i++){
        tmp = arr_col_sum[i-1] - (arr_col_sum[n-1]-arr_col_sum[i-1]);
        tmp = tmp>0?tmp:-tmp;
        if(min_col > tmp) min_col = tmp;
    }
    int res =  min_col>min_row?min_row:min_col;
    cout<<res<<endl;
}

链表

移除链表元素

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    ListNode* removeElements(ListNode* head, int val) {
        //新建一个虚拟头n_head,它的next指针指向原来头head所指的地址,head里存的就是head指向的地址,所以不需要在进一步用取地址符&取地址
        ListNode *n_head = new ListNode(); 
        n_head -> next = head;
        ListNode *cur = n_head;
        while(cur->next != NULL){
            if(cur->next->val == val){
                ListNode *tmp = cur->next;
                cur->next = cur->next->next;
                delete tmp;
            }
            else{
                cur = cur->next;
            }
           
        }
        ListNode * res = n_head->next;
        delete n_head;
        return res;
        
    }
};

设计链表

class MyLinkedList {
public:
    struct Node{
        int val;
        Node * next;
        Node(int val){
            this->val = val;
            this->next = nullptr;
        }
    };
    Node * vhead;
    int len;

    MyLinkedList() {
        vhead = new Node(0);
        len = 0;
    }
    
    int get(int index) {
        if(index+1>len || index<0) return -1;
        index++;
        Node * cur = vhead;
        while(index--){
            cur = cur->next;
        }
        return cur->val;
    }
    
    void addAtHead(int val) {
        Node* cur = vhead;
        Node* tmp = new Node(val);
        tmp->next = cur->next;
        cur->next = tmp;
        len++;
        
    }
    
    void addAtTail(int val) {
        Node * cur = vhead;
        int index = len;
        while(index--){
            cur = cur->next;
        }
        Node*tmp = new Node(val);
        cur->next = tmp;
        len++;

    }
    
    void addAtIndex(int index, int val) {
        if(index > len) return;
        if(index<0) index =0;
        Node* cur = vhead;
        Node* tmp = new Node(val);
        while(index--){
            cur = cur->next;
        }
        tmp->next = cur->next;
        cur->next = tmp;
        len++;
    }
    
    void deleteAtIndex(int index) {
        if(index>=len) return;
        if(index<0) return;
        Node* cur = vhead;
        while(index--){
            cur = cur->next;      
        }
        Node * tmp = cur->next;
        cur->next = cur->next->next;
        delete tmp;
        len--;
    }
};

/**
 * Your MyLinkedList object will be instantiated and called as such:
 * MyLinkedList* obj = new MyLinkedList();
 * int param_1 = obj->get(index);
 * obj->addAtHead(val);
 * obj->addAtTail(val);
 * obj->addAtIndex(index,val);
 * obj->deleteAtIndex(index);
 */

翻转列表

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    ListNode* reverseList(ListNode* head) {
        ListNode *fast = head;
        ListNode *slow = NULL;
        if(head == NULL) return head;
        ListNode *tmp = NULL;
        while(fast != NULL){
            tmp = fast;
            fast = fast->next;
            tmp->next = slow;
            slow = tmp;
        }
        return slow;
    }
};

两两交换链表中的节点

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    ListNode* swapPairs(ListNode* head) {
        if(head == NULL || head->next == NULL) return head;
        ListNode* vhead = new ListNode();
        vhead->next = head;
        ListNode* cur = vhead;
        ListNode* tmp = NULL;
        ListNode* tmp2 = NULL;
        ListNode* tmp3 = NULL;
        while(cur->next && cur->next->next){
            tmp = cur->next;
            tmp2 = cur->next->next;
            tmp3 = cur->next->next->next;
            cur->next = tmp2;
            cur->next->next = tmp;
            cur->next->next->next = tmp3;
            cur = cur->next->next;
        }
        return vhead->next;
    }
};

或者

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    ListNode* swapPairs(ListNode* head) {
        if(head == NULL || head->next == NULL) return head;
        ListNode* vhead = new ListNode();
        vhead->next = head;
        ListNode* cur = vhead;
        ListNode* tmp = NULL;
        ListNode* tmp2 = NULL;
        ListNode* tmp3 = NULL;
        while(cur->next && cur->next->next){
            tmp = cur->next;
            tmp2 = cur->next->next;
            tmp3 = cur->next->next->next;
            cur->next = tmp2;
            tmp2->next = tmp;
            tmp->next = tmp3;
            cur = tmp;
        }
        return vhead->next;
    }
};

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

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    ListNode* removeNthFromEnd(ListNode* head, int n) {
        ListNode* vhead = new ListNode();
        vhead->next = head;
        ListNode* fast = vhead;
        ListNode* slow = vhead;
        while(n--){
            if(fast->next){
                fast=fast->next;
            }
            else{
                return NULL;
            }
        }
        while(fast->next){
            fast = fast->next;
            slow = slow->next;
        }
        slow->next = slow->next->next;
        return vhead->next;

    }
};

链表相交

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
        int cnta = 0;
        int cntb = 0;
        ListNode * cur = headA;
        while(cur){
            cnta++;
            cur = cur->next;
        }
        cur = headB;
        while(cur){
            cntb++;
            cur = cur ->next;
        }
        int resi = cnta - cntb;
        ListNode *cura = headA;
        ListNode *curb = headB;
        if(resi >= 0){
            while(resi--){
                cura = cura->next;
            }
        }
        else{
            resi = -resi;
            while(resi--){
                curb = curb->next;
            }
        }
        while(cura && curb){
            if(cura == curb) return cura;
            cura = cura->next;
            curb = curb->next;
        }
        return nullptr;

    }
};

环形列表

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode *detectCycle(ListNode *head) {
        ListNode *fast = head;
        ListNode * slow = head;
        int cnt = 0;
        if(fast == NULL || fast->next == NULL){
            return NULL;
        }
        while(fast && fast->next && fast->next->next && slow && slow->next){
            fast = fast->next->next;
            slow = slow ->next;
            cnt++;
            if(fast == slow){
                ListNode* tmp1 = head;
                ListNode* tmp2 = slow;
                while(tmp1&&tmp2){
                    if(tmp1 == tmp2){
                        return tmp1;
                    }
                    tmp1 = tmp1->next;
                    tmp2 = tmp2->next;
                    cnt++;
                }
            }
        }
        return NULL;
    }
};

posted @ 2025-03-25 15:11  玉米面手雷王  阅读(19)  评论(0)    收藏  举报