算法日志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。
你不需要考虑数组中超出新长度后面的元素。
- 两层循环
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
- 双指针法
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;
}
};