剑指&leetcode刷题记录

class Solution {
public:
    int jumpFloorII(int number) 
    {
        return 1<<(number-1);
    }
};

题目:变态跳台阶

题目讲解:https://www.nowcoder.com/questionTerminal/22243d016f6b47f2a6928b4313c85387

 

 

题目:最小的K个数问题

class Solution {
public:
    vector<int> GetLeastNumbers_Solution(vector<int> input, int k) 
    {
        vector<int> result;
        priority_queue<int, vector<int>, greater<int> >  q;//greater<>是仿函数,用于申明小根堆
        int size = input.size();
        if(size < k) result;
        for(int i=0;i<size;++i)
        {
            q.push(input[i]);
        }
        for(int i=0;i<k;++i)
        {
            result.push_back(q.top());
            q.pop();
        }
        return result;
    }
};

本题还有个最优解:利用bfprt算法

 

题目 4:替换空格

解法1:用了额外空间的O(N)算法

class Solution {
public:
	void replaceSpace(char *str,int length) 
    {
        string s;
        char *p = str;
        while(*p != '\0')
        {
            if(*p != ' ')
                s += *p;
            else s += "%20";
            p++;
        }
        int i = 0;
        for(; i<s.size(); ++i)
        {
            str[i] = s[i];
        }
        str[i] = '\0';
	}
};

解法2:不用额外空间的O(N) 的算法

class Solution {
public:
	void replaceSpace(char *str,int length) 
    {
        int size = 0;
        if(str == NULL || length <=0)
            return ;
        int count = 0;
        while(str[size] != '\0')
        {
            if(str[size] == ' ') count ++;
            size++;
        }
        --size;
        int newLen = size + 2*count;
        if(newLen > length) return ;
        
        int indexOne = size;
        int indexTwo = newLen;
        
        while(indexOne>=0 && indexOne<indexTwo)
        {
            if(str[indexOne] == ' ')
            {
                str[indexTwo --] = '0';
                str[indexTwo --] = '2';
                str[indexTwo --] = '%';
            }
            else
            {
                str[indexTwo --] =str[indexOne]; 
            }
            --indexOne;
        }
	}
};

题目5:从尾到头打印链表

class Solution {
public:
    vector<int> printListFromTailToHead(ListNode* head) 
    {
        stack<int> myStack;
        vector<int> result;
        ListNode* n = head ;
        if(n == NULL)
            return result;
        while(n)
        {
            myStack.push(n->val);
            n = n->next;
        }
        while(!myStack.empty())
        {
            result.push_back(myStack.top());
            myStack.pop();
        }
        return result;
    }
};

经典的栈(递归)结构

 

面试题7:用两个栈实现队列

class Solution
{
public:
    void push(int node) 
    {
        stack1.push(node);
    }

    int pop() 
    {
        if(stack2.empty())
        {
            while(!stack1.empty())
            {
                stack2.push(stack1.top());
                stack1.pop();
            }
        }
        if(stack2.empty()) return -1;
        else
        {
            int result = stack2.top();
            stack2.pop();
            return result;
        }
    }

private:
    stack<int> stack1;
    stack<int> stack2;
};

leetcode:33. 搜索旋转排序数组

class Solution {
public:
    int fun(vector<int>& nums,int target,int begin,int end)
    {
        if(begin < 0 || end >=nums.size())
            return -1;
        int midan;
        if(nums[begin] == target) return begin;
        else if(nums[end] == target) return end;
        
        while(begin < end)
        {
            midan = (end+begin)/2;
            if(nums[midan] == target) return midan;
            else if(nums[midan] < target)
                begin = midan+1;
            else if(nums[midan] > target)
                end = midan-1;
        }
        if(begin == end && nums[begin] == target) return begin;
        else return -1;
    }
    int search(vector<int>& nums, int target) 
    {
        int size = nums.size();
        if(size == 0) return -1;
        int indexLeft = 0;
        int indexRight = size-1;
        int indexMidan = indexLeft;
        int indexMin;
        while(nums[indexLeft] > nums[indexRight])
        {
            indexMidan = (indexRight + indexLeft)/2;
            if(indexLeft+1 == indexRight)
                break;
            if(nums[indexLeft] < nums[indexMidan])//中点在左边数组,最小值在右边,不会是自己
                indexLeft = indexMidan;
            else if(nums[indexLeft] > nums[indexMidan])//中点在右边数组,最小值在左边,也可能是自己
                indexRight = indexMidan;
        }
        indexMin = indexRight;
        if(indexMin == 0)
            return fun(nums,target,0,size-1);
        else if(target <= nums[size-1] && target >= nums[indexMin])
            return fun(nums,target,indexMin,size-1);
        else if(target >=nums[0] && target <=nums[indexMin-1])
            return fun(nums,target,0,indexMin-1);
        return -1;
    }
};

leetcode:74. 搜索二维矩阵

log n + log m

class Solution {
public:
    bool searchMatrix(vector<vector<int>>& matrix, int target) 
    {
        int hang = matrix.size();
        if(hang == 0) return false;
        int lie = matrix[0].size();
        if(lie == 0) return false;
        int left = 0;
        int right = hang-1;
        int k = 0;
        int midan;
        while(left+1<right)
        {
            midan = (left+right) / 2;
            if(matrix[left][lie-1] > target)
            {
                k=left;
                break;
            }
            else if(matrix[left][lie-1] == target)
                return true;
            else if(matrix[left][lie-1] < target)
            {
                if(matrix[midan][lie-1] < target)
                    left = midan;
                else if(matrix[midan][lie-1] == target)
                    return true;
                else if(matrix[midan][lie-1] > target)
                    right = midan;
            }
            
        }
        if(matrix[left][lie-1] < target)
            k=right;
        
        left = 0;right=lie-1;
        while(left<right)
        {
            midan = (left+right) / 2;
            if(matrix[k][midan] == target) return true;
            else if(matrix[k][midan] < target) left = midan+1;
            else right = midan-1;
        }
        if(left == right && matrix[k][left] == target) return true;
        else return false;
    }
};

leetcode:191. 位1的个数

class Solution {
public:
    int hammingWeight(uint32_t n) 
    {
        int result = 0;
        while(n)
        {
            n &= (n-1);
            ++result;
        }
        return result;
    }
};

leetcode:136. 只出现一次的数字

class Solution {
public:
    int singleNumber(vector<int>& nums) 
    {
        int result=nums[0];
        int size = nums.size();
        for(int i=1;i<size;++i)
            result ^= nums[i];
        return result;
    }
};

 

leetcode:62. 不同路径

class Solution {
public:
    int uniquePaths(int m, int n) 
    {
        int** arr = new int*[m];
        for(int i=0;i<m;++i)
            arr[i] = new int[n];
        
        for(int i=0;i<m;++i)
            arr[i][0] = 1;
        for(int i=0;i<n;++i)
            arr[0][i] = 1;
        
        for(int i=1;i<m;++i)
        {
            for(int j=1;j<n;++j)
            {
                arr[i][j] = arr[i-1][j] + arr[i][j-1];
            }
        }
        return arr[m-1][n-1];
    }
};

leetcode:392. 判断子序列

class Solution {
public:
    bool isSubsequence(string s, string t) 
    {
        int ssize = s.size();
        int tsize = t.size();
        int j=0;
        for(int i=0;i<tsize;++i)
        {
            if(j == ssize) return true;
            if(t[i] == s[j]) ++j;
        }
        if(j == ssize) return true;
        return false;
    }
};

leetcode:922. 按奇偶排序数组 II

class Solution {
public:
    vector<int> sortArrayByParityII(vector<int>& arr) 
    {
        int size = arr.size();
        if(size == 0 && size == 1) return arr;
        int left = 1;
        int right = size - 2;
        while(left<size && right>=0)
        {
            while(left<size && (arr[left]&1) == 1)
                left+=2;
            while(right>=0 && (arr[right]&1) == 0)
                right-=2;
            if(left<size && right>=0)
                swap(arr[left],arr[right]);
        }
        return arr;
    }
};

剑指offer:反转链表


class Solution {
public:
    ListNode* ReverseList(ListNode* pHead) 
    {
        if(pHead == NULL)
            return NULL;
        ListNode* left = NULL;
        ListNode* right = pHead;
        ListNode* m = NULL;
        
        while(right)
        {
            left = m;
            m = right ;
            right = right->next;
            m->next = left;
        }
        return m;
        
        
        
        
        
       /* if(pHead == NULL)
            return NULL;
        ListNode* p = pHead;
        stack<ListNode*> myStack;
        while(p->next)
        {
            myStack.push(p);
        }
        pHead = p;
        while(!myStack.empty())
        {
            p->next = myStack.top();
            p = p->next;
            myStack.pop();
        }
        return pHead;*/
    }
};

剑指offer:倒数第k个链表节点


class Solution {
public:
    ListNode* FindKthToTail(ListNode* pListHead, unsigned int k) 
    {
        if(pListHead == NULL)
            return NULL;
        ListNode* left = pListHead;
        ListNode* right = left;
        for(int i=0;i<k-1;++i)
        {
            if(right->next == NULL)
                return NULL;
            right = right->next;
        }
        
        while(right->next)
        {
            left = left->next;
            right = right->next;
        }
        return left;
    }
};

剑指offer:合并有序链表

class Solution {
public:
    ListNode* Merge(ListNode* pHead1, ListNode* pHead2)
    {
        if(pHead1 == NULL)
            return pHead2;
        else if(pHead2 == NULL)
            return pHead1;
        
        if(pHead1->val < pHead2->val)
        {
            pHead1->next = Merge(pHead1->next,pHead2);
            return pHead1;
        }
        else if(pHead1->val >= pHead2->val)
        {
            pHead2->next = Merge(pHead1,pHead2->next);
            return pHead2;
        }
        else return NULL;
    }
};

剑指offer:第一个只出现一次的字符

class Solution {
public:
    int FirstNotRepeatingChar(string str) 
    {
        map<char,int> m;
        int arr[52];
        int size = str.size();
        if(size == 0) return -1;
        for(int i=0;i<size;++i)
        {
            map<char,int>::iterator it = m.find(str[i]);
            if(it == m.end())
                m.insert(pair<char,int>(str[i],1));
            else it->second++;
        }
        for(int i=0;i<size;++i)
        {
            map<char,int>::iterator it = m.find(str[i]);
            if(it == m.end()) continue;
            if(it->second == 1) return i;
        }
        return -1;
    }
};

剑指offer:包含min函数的栈

class Solution {
public:
    stack<int> myStack, minStack;
    
    void push(int value) 
    {
        myStack.push(value);
        if(minStack.empty()) minStack.push(value);
        else
        {
            int tim = minStack.top();
            if(tim <= value) minStack.push(tim);
            else minStack.push(value);
        }
    }
    void pop() 
    {
        if(myStack.empty())
            return;
        myStack.pop();
        minStack.pop();
    }
    int top() 
    {
        if(myStack.empty()) return -1;
        return myStack.top();
    }
    int min() 
    {
        if(minStack.empty())
            return -1;
        return minStack.top();
    }
};

剑指offer:数组中只出现一次的数字

class Solution {
public:
    void FindNumsAppearOnce(vector<int> data,int* num1,int *num2) 
    {
        vector<int> nums1;
        vector<int> nums2;
        int size = data.size();
        if(size < 2) return ;
        
        int tim = data[0];
        for(int i=1;i<size;++i)
        {
            tim^=data[i];
        }
        int re = 1;
        while((tim&re) == 0) re = (re << 1);
        for(int i=0;i<size;++i)
        {
            if((data[i]&re) == 0)nums1.push_back(data[i]);
            else nums2.push_back(data[i]);
        }
        int result1 = nums1[0];
        for(int i=1;i<nums1.size();++i)
            result1^=nums1[i];
        int result2 = nums2[0];
        for(int i=1;i<nums2.size();++i)
            result2^=nums2[i];
        *num1 = result1;
        *num2 = result2;
    }
};

leetcode:3. 无重复字符的最长子串

class Solution {
public:
    int lengthOfLongestSubstring(string s) 
    {
        map<char,int> m;
        int result = 0;
        int size = s.size();
        int left = 0;
        map<char,int>::iterator it;
        for(int i=0;i<size;++i)
        {
            it = m.find(s[i]);
            if(it == m.end())
            {
                m.insert({s[i],i});
            }
            else
            {
                left = it->second<left?left:(it->second+1);
                it->second = i;
            }
            
            result = result<(i-left+1)?(i-left+1):result;
        }
        return result;
    }
};

剑指offer:树的子结构


class Solution {
public:
    
    bool fun(TreeNode* p1,TreeNode* p2)
    {
        if(p2 == NULL) return true;
        if(p1 == NULL) return false;
        if(p1->val == p2->val)
            return fun(p1->left,p2->left) && fun(p1->right,p2->right);
        return false;
    }
    
    bool HasSubtree(TreeNode* pRoot1, TreeNode* pRoot2)
    {
        bool flag = false;
        if(pRoot1 == NULL || pRoot2 == NULL)
            return false;
        
        if(pRoot1->val == pRoot2->val)
        {
            flag =  fun(pRoot1,pRoot2);
        }
        if(flag == false)
        {
            flag = HasSubtree(pRoot1->left,pRoot2);
        }
        if(flag == false)
        {
            flag = HasSubtree(pRoot1->right,pRoot2);
        }
        return flag;
    }
};

剑指offer:二叉树的镜像


class Solution {
public:
    void Mirror(TreeNode *pRoot) 
    {
        if(pRoot == NULL) return;
        
        TreeNode* tim = pRoot->left;
        pRoot->left = pRoot->right;
        pRoot->right = tim;
        Mirror(pRoot->right);
        Mirror(pRoot->left);
    }
};

剑指offer:栈的压入,弹出序列

class Solution {
public:
    bool IsPopOrder(vector<int> pushV,vector<int> popV) 
    {
        int size1 = pushV.size();
        int size2 = popV.size();
        stack<int> myStack;
        int i = 0;
        int j = 0;
        while(i < size2)
        {
            if(myStack.empty()) myStack.push(pushV[j++]);
            if(popV[i] == myStack.top())
            {
                myStack.pop();
                ++i;
            }
            else if(j < size1)
            {
                myStack.push(pushV[j++]);
            }
            else
            {
               return false; 
            }
        }
        if(myStack.empty() && j == size1 && i==size2) return true;
        else return false;
        
    }
};

剑指offer:从上往下打印二叉树(层次遍历)

class Solution {
public:
    vector<int> PrintFromTopToBottom(TreeNode* root) 
    {
        vector<int> result;
        if(root == NULL) return result;
        queue<TreeNode*> myQueue;
        myQueue.push(root);
        TreeNode *tim;
        while(!myQueue.empty())
        {
            tim = myQueue.front();
            result.push_back(tim->val);
            if(tim->left != NULL) myQueue.push(tim->left);
            if(tim->right != NULL) myQueue.push(tim->right);
            myQueue.pop();
        }
        return result;
    }
};

剑指offer:二叉搜索树的后序遍历序列

class Solution {
public:
    bool fun(vector<int>& v,int begin,int end)
    {
        int size = v.size();
        if(begin < 0 || end >= size)
        {
            return false;
        }
        if(begin == end) return true;
        int root = end;
        int right = begin;
        for(int i = begin;i<end;++i)
        {
            if(v[i] < v[root]) right = i+1;
            else 
            {
                break;
            }
        }
        for(int i = right;i<end;++i)
        {
            if(v[i] < v[root]) return false; 
        }
        if(right == begin)
        {
            return fun(v,begin,end - 1);
        }
        if(right == end)
        {
            return fun(v,begin,end - 1);
        }
        return fun(v,begin,right-1) && fun(v,right,end-1);
    }
    
    bool VerifySquenceOfBST(vector<int> sequence) 
    {
        return fun(sequence, 0, sequence.size()-1);
    }
};

leetcode:55.跳跃游戏

class Solution {
public:
    bool  fun(vector<int>& nums, int index)
    {
        int size = nums.size();
        if(size == 0) return false;
        if(index == size-1) return true;
        else if(index > size-1) return false;
        bool result = false;
        for(int i=1;i<=nums[index];++i)
        {
            result |= fun(nums,index+i);
        }
        return result;
    }
    bool canJump(vector<int>& nums) 
    {
        return fun(nums,0);
    }
};

递归版本,leetcode上超时。

 

贪心版本

class Solution {
public:
    bool canJump(vector<int>& nums) 
    {
        int size = nums.size();
        int max = 0;
        for(int i=0;i<size;++i)
        {
            if(max < i) return false;
            max = max>(nums[i]+i)?max:(nums[i]+i);
        }
        return true;
    }
};

leetcode:23. 合并K个排序链表

class Solution {
public:
    
template<class _Ty = void>
struct greater1
{	
	constexpr bool operator()(const _Ty& _Left, const _Ty& _Right) const
	{	
		return (_Left->val > _Right->val);
	}
};
    
    ListNode* mergeKLists(vector<ListNode*>& lists) 
    {
        int size = lists.size();
        if(size == 0) return NULL;
        ListNode* result = NULL;
        ListNode* p = NULL;
        priority_queue<ListNode*, vector<ListNode*>, greater1<ListNode*>> test;
        
        for(int i=0;i<size;++i)
        {
            if(lists[i] != NULL)
                test.push(lists[i]);
        }
        while(!test.empty())
        {
            ListNode* top = test.top();
            test.pop();
            if(result == NULL) 
            {
                result = top;
                p = top;
            }
            else
            {
                p->next = top;
                p = p->next;
            }
            
            if(top != NULL && top->next != NULL)
            {
                test.push(top->next);
            }
        }
        return result;
        
    }
};

剑指offer:二叉树中和为某一值的路径


class Solution {
public:
    vector<vector<int>> result;
    void Find(TreeNode* root,int expectNumber,int preSum,vector<int>& myStack)
    {
        if(root == NULL) return ;
        
        preSum+=root->val;
        myStack.push_back(root->val);
        
        if(root != NULL && preSum == expectNumber && root->left == NULL && root->right == NULL)
        {
            result.push_back(myStack);
            myStack.pop_back();
            return ;
        }

        Find(root->left,expectNumber,preSum,myStack);
        Find(root->right,expectNumber,preSum,myStack);
        
        myStack.pop_back();
    }
    vector<vector<int>> FindPath(TreeNode* root,int expectNumber) 
    {
        if(root == NULL)
            return result;
        vector<int> myStack;
        Find(root,expectNumber,0,myStack);
        return result;
        
    }
};

剑指offer:数组中的逆序对

class Solution {
public:
    long mergeSort(vector<int>& nums, int begin, int end)
    {
        long result = 0;
        int size = nums.size();
        if(size == 0 || begin < 0 || end >= size)
            return 0;
        if(begin == end) return 0 ;
        int mid = (end + begin) >> 1;
        result += mergeSort(nums, begin, mid);
        result += mergeSort(nums, mid+1, end);
        vector<int> tim;
        int i = begin;
        int j = mid+1;
        while(i <= mid && j<=end)
        {
            if(nums[i] < nums[j])
            {
                tim.push_back(nums[i++]);
            }
            else 
            {
                result += (mid-i+1);
                tim.push_back(nums[j++]);
            }
        }
        while(i<=mid)
        {
            tim.push_back(nums[i++]);
        }
        while(j<=end)
        {
            tim.push_back(nums[j++]);
        }
        for(int k = 0;k<tim.size();++k)
        {
            nums[begin + k] = tim[k];
        }
        return result;
    }
    int InversePairs(vector<int> data) 
    {
        return mergeSort(data,0,data.size()-1)%1000000007;
    }
};

剑指offer:连续子数组的最大和

class Solution {
public:
    int FindGreatestSumOfSubArray(vector<int> array) 
    {
        int size = array.size();
        if(size == 0) return 0;
        int maxResult = array[0];
        int tim = 0;
        for(int i=0;i<size;++i)
        {
            tim+=array[i];
            maxResult = maxResult < tim?tim:maxResult;
            if(tim < 0) tim = 0;
        }
        return maxResult;
    }
};

剑指offer:最小的k个数

class Solution {
public:
    int partition(vector<int>& nums,int begin, int end)
    {
        int size = nums.size();
        if(size == 0 || begin < 0 || end >= size || end < begin)
            return -1;
        
        int index = (rand() % (end-begin+1))+ begin;
        int small = begin - 1;
        swap(nums[index],nums[end]);
        for(int i=begin;i<end;++i)
        {
            if(nums[i] < nums[end])
            {
                ++small;
                if(small != i) swap(nums[i],nums[small]);
            }
        }
        ++small;
        swap(nums[small], nums[end]);
        return small;
    }
    vector<int> GetLeastNumbers_Solution(vector<int> input, int k) 
    {
        int size = input.size();
        vector<int> result;
        if (size == 0) return result;
        if (k == size)
        {
            return input;
        }
        else if (k > size) return result;
        int begin = 0; int end = size - 1;
        int index = partition(input, begin, end);
        while (index != k)
        {
            if (index == -1) return result;
            else if (index < k)
            {
                begin = index + 1;
            }
            else if (index > k)
            {
                end = index - 1;
            }
            index = partition(input, begin, end);
        }
        int K = 0;
        for (int i = 0; i < size; ++i)
        {
            if (input[i] < input[index])
            {
                result.push_back(input[i]);
                ++K;
            }
        }
        for (; K < k; ++K)
        {
            result.push_back(input[index]);
        }
        return result;
    }
};

剑指offer:数组中出现次数超过一半的数

class Solution {
public:
    int partition(vector<int> nums,int begin, int end)
    {
        int size = nums.size();
        if(size == 0 || begin <0 || end >= size)
            return -1;
        
        int index = (rand() % (end-begin+1))+ begin;
        swap(nums[index],nums[end]);
        
        int small = begin - 1;
        for(int i=begin;i<end;++i)
        {
            if(nums[i] < nums[end])
            {
                ++small;
                if(small != i) swap(nums[small],nums[i]);
            }
        }
        ++small;
        swap(nums[small],nums[end]);
        return small;
    }
    int MoreThanHalfNum_Solution(vector<int> numbers) 
    {
        int size = numbers.size();
        if(size == 0) return 0;
        int mid = size >> 1;
        int index = 0;
        int begin = 0, end = size-1;
        while(index != mid)
        {
            if(index < mid)
            {
                begin = index+1;
            }
            else if(index > mid)
            {
                end = index-1;
            }
            index = partition(numbers,begin,end);
        }
        int count = 0;
        for(int i=0;i<size;++i)
        {
            if(numbers[i] == numbers[index]) ++count;
        }
        if(count > mid) return numbers[index];
        else return 0;
        
        
    }
};

剑指offer:两个链表的第一个公共节点


class Solution {
public:
    ListNode* FindFirstCommonNode( ListNode* pHead1, ListNode* pHead2) 
    {
        ListNode* result = NULL;
        if(pHead1 == NULL || pHead2 == NULL) return result;
        stack<ListNode*> s1,s2;
        ListNode* p = pHead1;
        while(p)
        {
            s1.push(p);
            p = p->next;
        }
        p = pHead2;
        while(p)
        {
            s2.push(p);
            p = p->next;
        }
        while(!s1.empty() && !s2.empty())
        {
            if(s1.top() == s2.top())
            {
                result = s1.top();
                s1.pop();
                s2.pop();
            }
            else
            {
                return result;
            }
        }
        return result;
    }
};

剑指offer:和为s的两个数字

class Solution {
public:
    vector<int> FindNumbersWithSum(vector<int> array,int sum) 
    {
        vector<int> result;
        int size = array.size();
        if(size<2) return result;
        map<int, int> m;
        
        for(int i=0;i<size;++i)
        {
            m.insert({array[i],i});
        }
        
        int tim, min = 0x7fffffff;
        for(int i=0;i<size;++i)
        {
            map<int, int>::iterator it = m.find(sum - array[i]);
            if(it != m.end() && it->second != i)
            {
                tim = array[i]*(it->first);
                if(tim < min)
                {
                    min = tim;
                    result.clear();
                    result.push_back(array[i]);
                    result.push_back(it->first);
                }
            }
        }
        return result;
    }
};

剑指offer:二叉树的深度

class Solution {
public:
    int treeDepth(TreeNode* root, int preDepth)
    {
        if(root == NULL) return preDepth;
        int left, right;
        left = treeDepth(root->left,preDepth+1);
        right = treeDepth(root->right,preDepth+1);
        return left>right?left:right;
    }
    int TreeDepth(TreeNode* pRoot)
    {
        return treeDepth(pRoot, 0);
    }
};

剑指offer:左旋转字符串

class Solution {
public:
    string LeftRotateString(string str, int n) 
    {
        int size = str.size();
        if(size <= 1) return str;
        n %= size;
        string s1 = "";
        string s2 = "";
        for(int i = 0;i<n;++i)
        {
            s1 += str[i];
        }
        for(int i = n;i<size;++i)
        {
            s2 += str[i];
        }
        return s2+s1;
    }
};

剑指offer:翻转单词顺序列

class Solution {
public:
    string ReverseSentence(string str) 
    {
        string s;
        map<int, string> m;
        int size = str.size();
        if(size == 0) return s;
        int count = 0;
        string k = " ";
        for(int i=0;i<size;++i)
        {
            string tim;tim += str[i];
            if((k == tim) && (!s.empty()))
            {
                m.insert({count++,s});
                s.clear();
            }
            else
            {
                s += str[i];
            }
        }
        if(!s.empty())
        {
            m.insert({count++,s});
            s.clear();
        }
        string result;
        for(int i=count-1;i>=0;--i)
        {
            map<int, string>::iterator it = m.find(i);
            if(it != m.end())
            {
                if(i != 0)
                    result += it->second + " ";
                else
                    result += it->second;
            }
        }
        return result;
    }
};

剑指offer:滑动窗口的最大值

class Solution {
public:
    vector<int> maxInWindows(const vector<int>& num, unsigned int size)
    {
        deque<int> q;
        vector<int> result;
        int nsize = num.size();
        if(nsize == 0 || size == 0) return result;
        
        for(int i=0;i<nsize;++i)
        {
            if(q.empty()) q.push_back(i);
            while(!q.empty() && num[q.back()] <= num[i])
            {
                q.pop_back();
            }
            q.push_back(i);
            if(q.front() == i-size) q.pop_front();
            if(i >= size-1) result.push_back(num[q.front()]);
        }
        return result;
    }
};

剑指offer:平衡二叉树

class Solution {
public:
    bool fun(TreeNode* root, int& preD)
    {
        if(root == NULL) 
        {
            preD = 0;
            return  true;
        }
        int left,right;
        bool result = true;
        result &= fun(root->left,left);
        result &= fun(root->right,right);
        preD = left>right?left+1:right+1;
        if(abs(left - right) > 1) return false;
        else return result;
    }
    bool IsBalanced_Solution(TreeNode* pRoot) 
    {
        int i = 0;
        return fun(pRoot,i);
    }
};

剑指offer:和为s的连续正数序列

class Solution {
public:
    vector<vector<int>> FindContinuousSequence(int sum) 
    {
        vector<vector<int>> result;
        if(sum < 3) return result;
        
        int left = 1,right = 2;
        int mid = sum/2+1;
        int tmp = 3;
        vector<int> v;
        while(left<mid)
        {
            if(tmp<sum)
            {
                ++right;
                tmp+=right;
            }
            else if(tmp>sum)
            {
                tmp-=left;
                ++left;
            }
            else if(tmp == sum)
            {
                v.clear();
                for(int i=left;i<=right;++i) v.push_back(i);
                result.push_back(v);
            }
        }
        return result;
    }
};

剑指offer:不用加减乘除做加法

class Solution {
public:
    int Add(int num1, int num2)
    {
        int n1, n2;
        do
        {
           n1 = num1^num2;
           n2 = (num1&num2)<<1;
            num1 = n1;
            num2 = n2;
        }while(num2);
        return num1;
    }
};

剑指offer:圆圈最后剩下的数

class Solution {
public:
    int LastRemaining_Solution(int n, int m)
    {
        if(n<1 || m<1) return -1;
        if(n == 1) return 0;
        return (LastRemaining_Solution(n-1,m)+m)%n;
    }
};

判断一个数组中哪些可能是partition函数调用后枢纽值

https://pintia.cn/problem-sets/994805260223102976/problems/994805278589960192


vector<int> fun(vector<int> nums)
{
	vector<int> result;
	int size = nums.size();
	if (size <= 1) return nums;
	int leftMax = 0x80000000;
	stack<int> s;
	for (int i = size - 1; i > 0; --i)
	{
		if (s.empty()) s.push(nums[i]);
		else if (s.top() > nums[i]) s.push(nums[i]);
		else s.push(s.top());
	}
	for (int i = 0; i < size; ++i)
	{
		if (nums[i] >= leftMax && (s.empty() || nums[i] <= s.top()))
		{
			result.push_back(nums[i]);
			leftMax = nums[i];
		}
		else
		{
			leftMax = leftMax < nums[i] ? nums[i] : leftMax;
		}
		if(!s.empty()) s.pop();
	}
	return result;
}

剑指offer:数据流中的中位数

class Solution {
public:
    priority_queue<int,vector<int>,greater<int>> min;
    priority_queue<int> max;
    void Insert(int num)
    {
        int tim = num;
		if (((min.size() + max.size()) & 1) == 0)//偶数
		{
			if (!max.empty() && num < max.top())
			{
				max.push(num);
				tim = max.top();
				max.pop();
			}
			min.push(tim);
		}
		else
		{
			if (!min.empty() && num > min.top())
			{
				min.push(num);
				tim = min.top();
				min.pop();
			}
			max.push(tim);
		}
    }

    double GetMedian()
    { 
        int size = min.size() + max.size();
        if((size & 1) == 1) return (double)min.top();
		else return ((double)max.top() + (double)min.top()) / 2;
    }

};

leetcode:1005. K 次取反后最大化的数组和

class Solution {
public:
    int largestSumAfterKNegations(vector<int>& A, int K) 
    {
        priority_queue<int,vector<int>,greater<int>> q;
        int size = A.size();
        if(size == 0) return 0;
        for(int i=0;i<size;++i)
        {
            q.push(A[i]);
        }
        while(K)
        {
            int tim = -1*q.top();
            q.pop();
            q.push(tim);
            K--;
        }
        int result = 0;
        while(!q.empty())
        {
            result += q.top();
            q.pop();
        }
        return result;
    }
};

leetcode:1007. 行相等的最少多米诺旋转

class Solution {
public:
    int find(int* arr,int size,int length)
    {
        int result = 0;
        int max = arr[0];
        for(int i=0;i<size;++i)
        {
            if(arr[i] >= max)
            {
                //if(arr[i] == length) return -1;
                result = i;
                max = arr[i];
            }
        }
        return result;
    }
    int minDominoRotations(vector<int>& A, vector<int>& B)
    {
       int leftMin = -1, rightMin = -1;
        int size = A.size();
        int arrA[7] = { 0,0,0,0,0,0,0 }, arrB[7] = { 0,0,0,0,0,0,0 };

        for (int i = 0; i < size; ++i)
        {
            arrA[A[i]]++;
            arrB[B[i]]++;
        }
        for (int i = 0; i < 6; ++i)
        {
            int j;
            int tim = find(arrA, 7, size);
            //if (tim == -1) return 0;
            for (j = 0; j < size; ++j)
            {
                if (A[j] != tim && B[j] != tim)
                {
                    break;
                }
            }
            if (j == size)
            {
                leftMin = size - arrA[tim];
                break;
            }
            arrA[tim] = 0;
        }
        for (int i = 0; i < 6; ++i)
        {
            int j;
            int tim = find(arrB, 7, size);
           // if (tim == -1) return 0;
            for (j = 0; j < size; ++j)
            {
                if (B[j] != tim && A[j] != tim)
                {
                    break;
                }
            }
            if (j == size)
            {
                rightMin = size - arrB[tim];
                break;
            }
            arrB[tim] = 0;
        }
        if (leftMin != -1 && rightMin != -1)
            return leftMin < rightMin ? leftMin : rightMin;
        else if (leftMin == -1) return rightMin;
        else return leftMin;
    }
};

剑指offer:二叉树的下一个节点

class Solution {
public:
    TreeLinkNode* GetNext(TreeLinkNode* root)
    {
        if(root == NULL) return NULL;
        TreeLinkNode* r = root;
        if(root->right != NULL)
        {
            TreeLinkNode* temp = root->right;
            while(temp->left != NULL)
            {
                temp = temp->left;
            }
            return temp;
        }
        else
        {
            while(root->next != NULL)
            {
                 if(root->next->left == root) return root->next;
                 else
                 {
                     root = root->next;
                 }
            }
            return NULL;
        }
        
    }
};

剑指offer:字符流中第一个不重复的字符

class Solution
{
public:
    int arr[256];
    int index;
    Solution()
    {
        index = 0;
        for(int i = 0;i<256;++i) arr[i] = -1;
    }
  //Insert one char from stringstream
    void Insert(char ch)
    {
        int t = (int)ch;
         if(arr[t] == -1) arr[t] = index;
         else arr[t] = -2;
        ++index;
    }
  //return the first appearence once char in current stringstream
    char FirstAppearingOnce()
    {
        int MinIndex = 0x7fffffff;
        char result = '#';
        for(int i=0;i<256;++i)
        {
            if(arr[i] >= 0 && MinIndex > arr[i])
            {
                MinIndex = arr[i];
                result = (char)i;
            }
        }
        return result;
        
    }

};

剑指offer:链表中环的入口节点

class Solution {
public:
    ListNode* MeetingNode(ListNode* head)
    {
        if(head == NULL) return NULL;
        ListNode* slow = head->next;
        if(slow == NULL) return NULL;
        ListNode* fast = slow->next;
        while(slow!=NULL && fast!=NULL)
        {
            if(slow == fast) return fast;
            slow = slow->next;
            fast = fast->next;
            if(fast->next != NULL)
            {
                fast = fast->next;
            }
            else return NULL;
        }
            
        return NULL;
    }
    ListNode* EntryNodeOfLoop(ListNode* head)
    {
        if(head == NULL) return NULL;
        ListNode* current = MeetingNode(head);
        if(current == NULL) return NULL;
        int count = 1;
        ListNode* tim = current->next;
        while(tim != current)
        {
            ++count;
            tim = tim->next;
        }
        
        ListNode* fast = head;
        ListNode* slow = head;
        while(count>0)
        {
            fast = fast->next;
            --count;
        }
        while(slow != fast)
        {
            slow=slow->next;
            fast=fast->next;
        }
        return fast;
    }
};

leetcode:997. 找到小镇的法官

class Solution {
public:
    int findJudge(int N, vector<vector<int>>& trust) 
    {
        int re = 0;
        int result = -1;
        if(N == 1) return 1;
        if(trust.empty()) return -1;
        int *arr = new int[N+1];
        for(int i=0;i<=N;++i) arr[i] = 0;
        map<int,int>m;
        map<int,int>::iterator it;
        int size = trust.size();
        for(int i=0;i<size;++i)
        {
            arr[trust[i][1]]++;
            m.insert({trust[i][0],trust[i][1]});
        }
        for(int i=1;i<=N;++i)
        {
            if(arr[i] == N-1)
            {
                ++re;
                
                it = m.find(i);
                if(it == m.end())
                {
                    result = i;
                }
            }
        }
        return (re!=1)?-1:result;
    }
};

leetcode:41. 缺失的第一个正数

class Solution {
public:
    int firstMissingPositive(vector<int>& nums) 
    {
        int size = nums.size();
        if(size == 0) return 1;
        for(int i=0;i<size;)
        {
            
            if(nums[i] != i+1)
            {
                if(nums[i]>0 && (nums[i] <= size) && nums[nums[i]-1] != nums[i]) 
                {
                    swap(nums[i],nums[nums[i]-1]);
                }
                else ++i;
            }
            else ++i;
        }
        for(int i=0;i<size;++i)
        {
            if(nums[i] != i+1) return i+1;
        }
        return size+1;
    }
};

剑指offer:二叉搜索树的第k个节点

class Solution {
public:
    vector<TreeNode*> v;
    void fun(TreeNode* root)
    {
        if(root == NULL) return;
        fun(root->left);
        v.push_back(root);
        fun(root->right);
    }
    TreeNode* KthNode(TreeNode* root, int k)
    {
        if(k == 0 || root == NULL) return NULL;
        fun(root);
        if(k<=v.size()) return v[k-1];
        else return NULL;
    }
}  

剑指offer:把二叉树打印成多行


class Solution {
public:
        vector<vector<int> > Print(TreeNode* root) 
        {
            queue<TreeNode*> q;
            vector<vector<int>> result;
            int current = 1;
            int nexth = 0;
            if(root == NULL) return result;
            TreeNode* p = root;
            q.push(p);
            while(!q.empty())
            {
                
                vector<int> v;
                while(current)
                {
                    TreeNode* t = q.front();
                    v.push_back(t->val);
                    if(t->left != NULL) 
                    {
                        q.push(t->left);
                        ++nexth;
                    }
                    if(t->right != NULL)
                    {
                        q.push(t->right);
                        ++nexth;
                    }
                    q.pop();
                    --current;
                }
                current = nexth;
                nexth = 0;
                result.push_back(v);
                v.clear();
            }
            return result;
        }
    
};

剑指offer:按之子型打印二叉树


class Solution {
public:
    vector<vector<int> > Print(TreeNode* root)
    {
        vector<vector<int>> result;
        if(root == NULL) return result;
        stack<TreeNode*> qi;
        stack<TreeNode*> ou;
        qi.push(root);
        int hang = 1;
        vector<int> v;
        while(!qi.empty() || !ou.empty())
        {
            if(hang&1)
            {
                v.clear();
                while(!qi.empty())
                {
                    TreeNode* tim = qi.top();
                    v.push_back(tim->val);
                    if(tim->left != NULL) ou.push(tim->left);
                    if(tim->right != NULL) ou.push(tim->right);
                    qi.pop();
                }
                ++hang;
                result.push_back(v);
            }
            else
            {
                v.clear();
                while(!ou.empty())
                {
                    TreeNode* tim = ou.top();
                    v.push_back(tim->val);
                    if(tim->right != NULL) qi.push(tim->right);
                    if(tim->left != NULL) qi.push(tim->left);
                    ou.pop();
                }
                ++hang;
                result.push_back(v);
            }
        }
        return result;
    }
      
};

剑指offer:对称的二叉树


class Solution {
public:
    bool isSymmetrical(TreeNode* root1,TreeNode* root2)
    {
        if(root1==NULL && root2==NULL) return true;
        if(root1==NULL || root2==NULL) return false;
        if(root1->val == root2->val)
        {
            return isSymmetrical(root1->left,root2->right) && isSymmetrical(root1->right,root2->left);
        }
        return false;
    }
    bool isSymmetrical(TreeNode* root)
    {
        return isSymmetrical(root,root);
    }
 
};

leetcode:

26. 删除排序数组中的重复项

class Solution {
public:
    int removeDuplicates(vector<int>& nums) 
    {
        int size = nums.size();
        if(size <= 1) return size;
        int fast=1,slow=0;
        while(fast<size)
        {
            if (nums[fast] != nums[slow]) nums[++slow] = nums[fast];
            ++fast;
        }
        return slow+1;
    }
};

leetcode:

33. 搜索旋转排序数组

class Solution {
public:
    int fun(vector<int>& nums, int target,int left, int right)
    {
        int size = nums.size();
        if(size == 0) return -1;
        if(left < 0 || right >=size) return -1;
        int begin = left;
        int end = right;
        int midan;
        while(begin <= end)
        {
            midan = (begin + end)/2;
            if(nums[midan] == target) return midan;
            if(nums[midan] < target) begin = midan+1;
            else if(nums[midan] > target) end = midan-1;
        }
        return -1;
    }
    int search(vector<int>& nums, int target) 
    {
        int size = nums.size();
        if(size == 0) return -1;
        else if(size == 1) return nums[0] == target?0:-1;
       
        
        if(nums[0] < nums[size-1])
        {
            return fun(nums,target,0,size-1);
        }
        else
        {
            int midan;
            int begin = 0,end = size-1;
            while(begin < end-1)
            {
                midan = (begin+end)/2;
                if(nums[midan] > nums[end]) begin = midan;
                else if(nums[midan] < nums[begin]) end = midan;
            }
            int min = end;
            int result = fun(nums,target,0,min-1);
            if(result != -1) return result;
            return fun(nums,target,min,size-1);
        }
        
    }
};

leetcode:80. 删除排序数组中的重复项 II

class Solution {
public:
    int removeDuplicates(vector<int>& nums) 
    { 
        int size = nums.size();
        if(size <= 2) return size;
        int fast=1,slow=0;
        int current = nums[slow];
        int count = 1;
        while(fast<size)
        {
            if(nums[fast] == current && count < 2)
            {
                ++count;
                nums[++slow] = nums[fast];
            }
            else if(nums[fast] != current)
            {
                count = 1;
                current = nums[fast];
                nums[++slow] = nums[fast];
            }
            
            //if (nums[fast] != nums[slow]) nums[++slow] = nums[fast];
            ++fast;
        }
        return slow+1;
    }
};

leetcode:153. 寻找旋转排序数组中的最小值

class Solution {
public:
    int findMin(vector<int>& nums) 
    {
        int size = nums.size();
        if(size == 0) return -1;
        if(size == 1) return nums[0];
        if(nums[0] < nums[size-1]) return nums[0];
        
        int begin = 0;int end = size-1;
        int midan;
        while(begin < end-1)
        {
            midan = (begin+end)/2;
            if(nums[midan] > nums[begin]) begin = midan;
            else if(nums[midan] < nums[end]) end = midan;
        }
        return nums[end];
    }
};

算法第四版:二叉搜索树增删改查的实现


class Node
{
public:
	int key;
	char value;
	Node* left;
	Node* right;
	int N;
	Node()
	{

	}
	Node(int key, char value, int N)
	{
		this->key = key;
		this->value = value;
		this->N = N;
	}
};
class BST:Node
{
	Node* root;
public:
	BST()
	{
		root = NULL;
	}
	int size(Node* r)
	{
		if (r == NULL) return 0;
		return r->N;
	}
	char get(int key);
	char get(Node* x, int key);
	void insert(int key, char value);
	Node* insert(Node* x, int key, int value);
	int min();
	Node* min(Node* x);
	int select(int k);
	Node* select(Node* x, int k);
	int rank(int key);
	int rank(int key, Node* x);
	void deleteMin();
	Node* deleteMin(Node* x);
	void delete_BST(int key);
	Node* delete_BST(Node* x, int key);

};
char BST::get(int key)
{
	char result = '\0';
	if (root == NULL) return result;
	return get(root, key);
}
char BST::get(Node* x, int key)
{
	char result = '\0';
	if (x == NULL) return result;
	if (x->key == key) return x->value;
	if (x->key < key) return get(x->right, key);
	if (x->key > key) return get(x->left, key);
}
void BST::insert(int key, char value)
{
	root = insert(root, key, value);
}

Node* BST::insert(Node* x, int key, int value)
{
	if (x == NULL)
	{
		Node* NewNode = new Node(key,value,1);
		return NewNode;
	}
	if (x->key < key) x->right = insert(x->right, key, value);
	else if (x->key > key) x->left = insert(x->left, key, value);
	else if (x->key == key) x->value = value;

	x->N = size(x->left) + size(x->right) + 1;
	return x;
}

int BST::min()
{
	Node* result = min(root);
	if (root == NULL) return 0;
	return result->key;
	
}
Node* BST::min(Node* x)
{
	if (x == NULL) return NULL;
	if (x->left != NULL) return min(x->left);
	return x;
}

int BST::select(int k)
{
	Node* result = select(root, k);
	if (result == NULL) return 0;
	return result->key;
}
Node* BST::select(Node* x, int k)
{
	if (x == NULL) return NULL;
	int t = 0;
	if (x->left != NULL) t = size(x->left);
	if (t < k) return select(x->right, k - 1 - t);
	if (t == k) return x;
	if (t > k) return select(x->left, k);
}

void BST::deleteMin()
{
	if (root == NULL) return;
	Node* result = deleteMin(root);
	//delete result;
	//result = NULL;
}
/*
Node* BST::deleteMin(Node* x)
{
	if (x == NULL) return NULL;
	Node* dMin = min(x);
	if (dMin == NULL) return NULL;
	*dMin = *(dMin->right);
	return dMin;
}*/
Node* BST::deleteMin(Node* x)
{
	if (x == NULL) return NULL;
	if (x->left == NULL) return x->right;
	x->left = deleteMin(x->left);
	x->N = size(x->left) + size(x->right) + 1;
	return x;
}

int BST::rank(int key)
{
	return rank(key, root);
}
int BST::rank(int key, Node* x)
{
	if (x == NULL) return 0;
	int t = x->left == NULL ? 0 : x->left->N;
	if (x->key > key) return rank(key, x->left);
	if (x->key == key) return t;
	if (x->key < key) return rank(key, x->right) + t + 1;
}

void BST::delete_BST(int key)
{
	delete_BST(root, key);
}
Node* BST::delete_BST(Node* x, int key)
{
	if (x == NULL) return NULL;
	if (key == x->key)
	{
		if (x->right == NULL) return x->left;
		if (x->left == NULL) return x->right;
		
		Node* p = x;
		x = min(x->right);
		if (x == NULL) return x->left;
		x->left = p->left;
		x->right = deleteMin(p->right);
		delete p;
		p = NULL;
	}
	else if (key < x->key) x->left = delete_BST(x->left, key);
	else if (key > x->key) x->right = delete_BST(x->right, key);
	x->N = size(x->left) + size(x->right) + 1;
	return x;
}

leetcode:154. 寻找旋转排序数组中的最小值 II

class Solution {
public:
    int sort(vector<int>& nums)
    {
        int size = nums.size();
        int result = nums[0];
        for(int i = 1;i<size;++i) result = result > nums[i] ? nums[i] : result;
        return result;
    }
    int findMin(vector<int>& nums) 
    {
        int result;
        int size = nums.size();
        if(size == 1) return nums[0];
        int left = 0;
        int right = size-1;
        if(nums[0] < nums[right]) return nums[0];
        int midan;
        while(left < right-1)
        {
            midan = (left+right)>>1;
            if(nums[midan] == nums[left] && nums[midan] == nums[right]) 
            {
                result = sort(nums);
                return result;
            }
            if(nums[midan] < nums[left]) right = midan;
            else if(nums[midan] > nums[right]) left = midan;
        }
        return nums[right];
    }
};

leetcode:11. 盛最多水的容器

class Solution {
public:
    int maxArea(vector<int>& height) 
    {
        int size = height.size();
        if(size <= 1) return 0;
        int left = 0;
        int right = size-1;
        int result = 0;
        while(left<right)
        {
            int tim = height[left]<height[right]?height[left]:height[right];
            result = result > ((right - left)*tim) ? result : ((right - left)*tim);
            if(height[left] < height[right]) ++left;
            else --right;
        }
        return result;
    }
};

leetcode:题目号:200 575 695 268  674 135 代码略

leetcode:560 209 112 113 108

左神书题:最大值减去最小值小于等于num的子数组数量

leetcode:795

class Solution {
public:
    int numSubarrayBoundedMax(vector<int>& arr, int max)
    {
        int ret = 0;
        int temp = 0;
        int size = arr.size();
        for(int i=0;i<size;++i)
        {
            if(arr[i] <= max)
            {
                temp++;
                ret+=temp;
            }
            else temp = 0;
        }
        return ret;
    }
    int numSubarrayBoundedMax(vector<int>& arr, int L, int R) 
    {
        // 最大元素满足大于等于L小于等于R的子数组个数 = 最大元素小于等于R的子数组个数 - 最大元素小于L的子数组个数
        int size = arr.size();
        if(size == 0) return 0;
        return numSubarrayBoundedMax(arr,R)-numSubarrayBoundedMax(arr,L-1);
    }
};

leetcode: 98 35 104 110 111 102

 

leetcode:96不同的二叉搜索树

/*结题思路:假设n个节点存在二叉排序树的个数是G(n),1为根节点,2为根节点,...,n为根节点,当1为根节点时,其左子树节点个数为0,右子树节点个数为n-1,同理当2为根节点时,其左子树节点个数为1,右子树节点为n-2,所以可得G(n) = G(0)*G(n-1)+G(1)*(n-2)+...+G(n-1)*G(0)*/

class Solution {
    public int numTrees(int n) 
    {
        if(n<2) return 1;
        int[] arr = new int [n+1];
        arr[0] = 1;
        arr[1] = 1;
        
        for(int i=2;i<n+1;++i)
        {
            for(int j=0;j<i;++j)
            {
                arr[i] += arr[j]*arr[i-1-j];
            }
        }
        return arr[n];
    }
}
//c++溢出  所以用java

leetcode:100,94,230,144,116,117,111 ,129  130  199   96  137 141 142  287 101 222  235 236 404
在两个长度相等的排序数组中找到上中位数
84 85 221 513  542  718  581  27  283  485  1004 

1 15 34 42 53 121 122 62 63
75 88 167 653 344  345 215
342 231 191 338  349 350 

242  438 290  205 525 

451 347  49  快速幂 1002 56 204

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值