BM1 反转链表
ListNode* ReverseList(ListNode* pHead) {
if(pHead->val==NULL)
return NULL;
ListNode* cur=pHead;
ListNode* pre=NULL;
while(cur){
ListNode * temp= cur->next;
cur->next=pre;
pre=cur;
cur=temp;
}
return pre;
}
把每一个结点的next指针指向前一个结点即可,返回原来最后一个结点。
BM2 链表内指定区间反转
ListNode* reverseBetween(ListNode* head, int m, int n) {
// 增加的表头,最终返回res->next
ListNode* res = new ListNode(-1);
res->next = head;
// pre和cur
ListNode* pre = res;
ListNode* cur = head;
// find m
for (int i = 1; i < m; i++) {
pre = cur;
cur = cur->next;
}
// m to n
for (int i = m; i < n; i++) {
ListNode* temp = cur->next;
cur->next = temp->next;
temp->next = pre->next;
pre->next = temp;
}
return res->next;
}
将m~n结点依次插到m-1后。
BM4 合并两个排序的链表
ListNode* Merge(ListNode* pHead1, ListNode* pHead2) {
// 一个为空则返回另一个
if (pHead1 == NULL)
return pHead2;
if (pHead2 == NULL)
return pHead1;
// head cur
ListNode* head = new ListNode(0);// 返回head->next
ListNode* cur = head;
// 比较
while (pHead1 && pHead2) {
if (pHead1->val <= pHead2->val) {
cur->next = pHead1;
pHead1 = pHead1->next;
}
else {
cur->next = pHead2;
pHead2 = pHead2->next;
}
cur=cur->next;
}
// 剩余
if (pHead1)
cur->next = pHead1;
else
cur->next = pHead2;
return head->next;
}
两个链表的top进行比较。
BM6 判断链表中是否有环
bool hasCycle(ListNode *head) {
// 判断是否为空
if (head == NULL)
return false;
// 快慢双指针
ListNode* fast = head;
ListNode* slow = head;
// 如果没环,快指针会先到链表尾
while (fast != NULL && fast->next != NULL) {
// 快指针移动两步
// 慢指针移动一步
slow = slow->next;
fast = fast->next->next;
// 快慢指针相遇说明有环
if (fast == slow)
return true;
}
// 如果能到末尾,则没有环
return false;
}
快指针一次两步,慢指针一次一步。
BM17 二分查找
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param nums int整型vector
* @param target int整型
* @return int整型
*/
int search(vector<int>& nums, int target) {
// write code here
int l = 0;
int r = nums.size() - 1;
while (l <= r) {
int m = (l + r) / 2;
if (nums[m] == target)
return m;
if (nums[m] > target)
r = m - 1;
else
l = m + 1;
}
return -1;
}
排序后可以用二分。
BM18 二维数组中的查找
bool Find(int target, vector<vector<int> > array) {
//优先判断特殊
if(array.size() == 0)
return false;
int n = array.size();
if(array[0].size() == 0)
return false;
int m = array[0].size();
//从最左下角的元素开始往左或往上
for(int i = n - 1, j = 0; i >= 0 && j < m; ){
//元素较大,往上走
if(array[i][j] > target)
i--;
//元素较小,往右走
else if(array[i][j] < target)
j++;
else
return true;
}
return false;
}
从左下角开始,小则右移,大则上移。
BM19 寻找峰值
int findPeakElement(vector<int>& nums) {
// write code here
int l=0;
int r=nums.size()-1;
while(l<r){
int mid=(l+r)/2;
// 若mid右侧向上,则右侧一定能找到波峰
// 若mid右侧向下,则右侧不一定能找到波峰,所以把视线转向左侧
if(nums[mid]<nums[mid+1]){
l=mid+1;
}
else{
r=mid;
}
}
return r;
}
若mid是向上的趋势,则在其右侧一定能找到波峰;
若mid是向下的趋势,则在其右侧未必能找到波峰,在其左侧一定能找到波峰。
BM21 旋转数组的最小数字
int minNumberInRotateArray(vector<int> rotateArray) {
if(rotateArray.size()==1)
return rotateArray[0];
int left = 0;
int right = rotateArray.size() - 1;
while(left < right){
int mid = (left + right) / 2;
//最小的数字在mid右边
if(rotateArray[mid] > rotateArray[right])
left = mid + 1;
//无法判断,一个一个试
else if(rotateArray[mid] == rotateArray[right])
right--;
//最小数字要么是mid要么在mid左边
else
right = mid;
}
return rotateArray[left];
}
判断最小数字在mid的左右。
BM42 用两个栈实现队列
public:
void push(int node) {
stack1.push(node);
}
int pop() {
while (stack1.empty() == 0) {
stack2.push(stack1.top());
stack1.pop();
}
int res = stack2.top();
stack2.pop();
while (stack2.empty() == 0) {
stack1.push(stack2.top());
stack2.pop();
}
return res;
}
private:
stack<int> stack1;
stack<int> stack2;
两个栈来回倒腾数据。
BM43 包含min函数的栈
stack<int> s1,s2;
// s1存储value,s2存储截至目前的min
void push(int value) {
s1.push(value);
if(s2.empty()||value<s2.top()){
s2.push(value);
}
else{
s2.push(s2.top());
}
}
void pop() {
s1.pop();
s2.pop();
}
int top() {
return s1.top();
}
int min() {
return s2.top();
}
min stack用于存储截至目前的min
BM44 有效括号序列
bool isValid(string s) {
// write code here
stack<char> st;
for(int i=0;i<s.length();i++){
if(s[i]=='('){
st.push(')');
}
else if(s[i]=='['){
st.push(']');
}
else if(s[i]=='{'){
st.push('}');
}
else if(st.empty()){
return false;
}
else if(s[i]==st.top()){
st.pop();
}
}
if(st.empty())
return true;
else
return false;
}
stack的应用。