文章目录
session Ⅰ Algorithm
problem Ⅰ
876. Middle of the Linked List
Given the head of a singly linked list, return the middle node of the linked list.
If there are two middle nodes, return the second middle node.
Example 1:
Input: head = [1,2,3,4,5]
Output: [3,4,5]
Explanation: The middle node of the list is node 3.
Example 2:
Input: head = [1,2,3,4,5,6]
Output: [4,5,6]
Explanation: Since the list has two middle nodes with values 3 and 4, we return the second one.
/**
* 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* middleNode(ListNode* head) {
ListNode *fast, *slow;
fast=slow=head;
while(fast!=NULL && fast->next!=NULL){
fast = fast->next->next;
slow = slow->next;
}
return slow;
}
};
NOTE:
my solution is that, use two pointer, one is fast pointer, and the other is slow pointer
for fast pointer, take two steps in each cycle, and for slow pointer, take one step
and the judge boundary is that:
- fast is nullptr when the length of linkList is evennumbers
- fast->next is nullptr when the length of linkList is odd number
problem Ⅱ
19. Remove Nth Node From End of List
Given the head of a linked list, remove the nth node from the end of the list and return its head.
Example 1:
Input: head = [1,2,3,4,5], n = 2
Output: [1,2,3,5]
Example 2:
Input: head = [1], n = 1
Output: []
Example 3:
Input: head = [1,2], n = 1
Output: [1]
/**
* 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 *q, *pre, *tmp;
q=pre=head;
int len=1;
while(q->next != NULL){
q = q->next;
++len;
}
// list empty after delete
if(len==1)return NULL;
// delete head
if(len==n){
head = head->next;
delete pre;
return head;
}
// normal
for(int i=0; i<len-n-1; i++)pre=pre->next;
tmp = pre->next;
pre->next = tmp->next;
delete tmp;
return head;
}
};
session Ⅱ DataStructure
problem Ⅰ
240. Search a 2D Matrix II
Write an efficient algorithm that searches for a target value in an m x n integer matrix. The matrix has the following properties:
- Integers in each row are sorted in ascending from left to right.
- Integers in each column are sorted in ascending from top to bottom.
Example 1:
Input: matrix = [[1,4,7,11,15],[2,5,8,12,19],[3,6,9,16,22],[10,13,14,17,24],[18,21,23,26,30]], target = 5
Output: true
Example 2:
Input: matrix = [[1,4,7,11,15],[2,5,8,12,19],[3,6,9,16,22],[10,13,14,17,24],[18,21,23,26,30]], target = 20
Output: false
class Solution {
public:
bool searchMatrix(vector<vector<int>>& matrix, int target) {
int m=matrix.size(), n=matrix[0].size(), i=0, j=n-1;
while(i<m && j>=0){
if(matrix[i][j] < target)i++;
else if(matrix[i][j] > target)j--;
else return true;
}
return false;
}
};
NOTE:
my solution is like kind of linear search, we all know that the 2-d matrix’s rows is descend from right to left, and col is descend from bottom to top
so we could use search from right to left and from top to bottom
Upper bound of time complexity is O ( n + m ) O(n+m) O(n+m)
problem Ⅱ
435. Non-overlapping Intervals
Given an array of intervals intervals where intervals[i] = [starti, endi], return the minimum number of intervals you need to remove to make the rest of the intervals non-overlapping.
Example 1:
Input: intervals = [[1,2],[2,3],[3,4],[1,3]]
Output: 1
Explanation: [1,3] can be removed and the rest of the intervals are non-overlapping.
Example 2:
Input: intervals = [[1,2],[1,2],[1,2]]
Output: 2
Explanation: You need to remove two [1,2] to make the rest of the intervals non-overlapping.
Example 3:
Input: intervals = [[1,2],[2,3]]
Output: 0
Explanation: You don’t need to remove any of the intervals since they’re already non-overlapping.
this problem is really similar to this
my wrong solution
class Solution {
public:
int eraseOverlapIntervals(vector<vector<int>>& intervals) {
sort(intervals.begin(), intervals.end());
vector<vector<int>> merged;
int count = 0;
for(auto interval : intervals){
// nooverlapped
if(merged.empty() || merged.back()[1] <= interval[0])
merged.push_back(interval);
// back bigger
else if((merged.back()[1]-merged.back()[0]) > (interval[1]-interval[0])){
//merged.back() = interval;
merged.back()[1] = max(merged.back()[1], interv[1]);// merge
count++;
}
// interval bigger or interval == back
else {
count++;
continue;
}
}
return count;
}
};
my success solution
class Solution {
public:
int eraseOverlapIntervals(vector<vector<int>>& interval) {
sort(interval.begin(), interval.end());
vector<int> merged = interval[0];
int count = 0;
for(int i=1; i<interval.size(); i++){
if(merged[1] > interval[i][0]){
merged[1] = min(merged[1], interval[i][1]);
count++;
}else merged = interval[i];
}
return count;
}
};
my faster solution
class Solution {
public:
int eraseOverlapIntervals(vector<vector<int>>& interval) {
sort(interval.begin(), interval.end());
int merged = interval[0][1];
int count = 0;
for(int i=1; i<interval.size(); i++){
if(merged > interval[i][0]){
merged = min(merged, interval[i][1]);
count++;
}else merged = interval[i][1];
}
return count;
}
};
NOTE:
my solution is that:
first we sort the intervals, and than the state of the interval is like that
so everytime we choose the min end, and the start is not important