刷题练手-《程序员面试金典》(不断更新)

在这里插入图片描述

class Solution {
public:
    bool isUnique(string astr) {
        if(astr.size()==0)return true;
        unordered_set<char>myset={astr[0]};
        for(int i=1;i<astr.size();i++)
        {
            if(myset.find(astr[i])!=myset.end())
            return false;
            myset.insert(astr[i]);
        }
        return true;


    }
};

在这里插入图片描述

class Solution {
public:
    bool CheckPermutation(string s1, string s2) {
        unordered_map<char, int> mp;
        for(int i = 0; i < s1.size(); i ++)
            mp[s1[i]] ++;
        for(int i = 0; i < s2.size(); i ++)
            mp[s2[i]] --;
        unordered_map<char, int>::iterator it;
        for(it = mp.begin(); it != mp.end(); it++)
        {
            if(it->second != 0) return false;
        }
        return true;
    }
};

在这里插入图片描述
这题也是见了不知道多少次了,先补充一下数组,再从后往前双指针。

class Solution {
public:
    string replaceSpaces(string S, int length) {
        int count=0;
       
        for(int i=0;i<length;i++)
        {
            if(S[i]==' ')
            {
                count++;
            }
        }
        if(count==0)return S;
        int p1=length-1;
        int p2=length+2*count -1;
        while(p1>=0&&p1<=p2)
        {
            if(S[p1]!=' ')
            {
                S[p2--]=S[p1--];
            }
            else
            {
                p1--;
                S[p2--]='0';
                S[p2--]='2';
                S[p2--]='%';
            }
        }
        return S.substr(0,length+2*count);


    }
};

在这里插入图片描述
这种题目就是秒杀。

class Solution {
public:
    bool canPermutePalindrome(string s) {
        //最多允许一个字符出现奇数次,其余字符必须都出现偶数次
        unordered_map<char,int>mp;
        for(int i=0;i<s.size();i++)
        {
            mp[s[i]]++;
        }
        int odd_count=1;//奇数
        for(auto it=mp.begin();it!=mp.end();it++)
        {
            if(it->second%2 != 0)
            {
                if(odd_count==0)
                {
                    return false;
                }
                else
                {
                    odd_count--;
                }

            }
        }
        return true;

    }
};

在这里插入图片描述
这题就是简单的分类讨论即可。

class Solution {
public:
	bool oneEditAway(string first, string second) {
		//字符数相差大于1,false
		//字符数相等,判断first和second中有两个及以上个字符不相同,返回false
		//字符数相差等于1,将长字符串删掉一个后和短的比较是否完全相同
		int first_len = first.size();
		int second_len = second.size();
		if (first_len == second_len)
		{
			int count = 0;
			for (int i = 0; i<first_len; i++)
			{
				if (first[i] != second[i])
					count++;
			}
			if (count >= 2)return false;
			return true;

		}
		else if (abs(first_len - second_len) == 1)
		{
			if (first_len>second_len)
			{
				return fun(first, second);
			}
			else
			{
				return fun(second, first);
			}

		}
		else
		{
			return false;
		}

	}

	bool fun(string&long_str, string&short_str)
	{
		for (int i = 0; i<long_str.size(); i++)
		{

			string temp = long_str;
			temp.erase(i, 1);//string& erase ( size_t pos = 0, size_t n = npos );
			if (isEqual(temp, short_str))
				return true;
				
		}
		return false;

	}
	bool isEqual(const string&s1, const string&s2)
	{
		for (int i = 0; i<s1.size(); i++)
		{
			if (s1[i] != s2[i])
				return false;
		}
		return true;
	}
};

在这里插入图片描述
这道题双指针很简单,唯一需要注意的是需要使用to_string函数,将数值转化为字符串并返回对应的字符串。

class Solution {
public:
    string compressString(string S) {
        //双指针遍历
        
        string res;
        int i=0,j=0;
        while(i<S.size())
        {
            int count=0;
            while(j<S.size()&&S[i]==S[j])
            {
                count++;
                j++;
            }
            res.append(1,S[i]);
            res.append(to_string(count));//必须使用to_string函数!!!

            i=j;
        }

        if(res.size()<S.size())
        return res;

        return S;


    }
};

在这里插入图片描述
这题应该还有其他更好的方法,我自己第一感觉是这个方法:

class Solution {
public:
	void setZeroes(vector<vector<int>>& matrix) {
		set<int>rows;
		set<int>cols;
		for (int i = 0; i<matrix.size(); i++)
			for (int j = 0; j<matrix[0].size(); j++)
			{
				if (matrix[i][j] == 0)
				{
					rows.insert(i);
					cols.insert(j);
				}
			}
		for (auto it = cols.begin(); it != cols.end(); it++)//按列清零
			for (int i = 0; i<matrix.size(); i++)
			{
				matrix[i][*it] = 0;
			}
		for (auto it = rows.begin(); it != rows.end(); it++)//按行清零
			for (int i = 0; i<matrix[0].size(); i++)
			{
				matrix[*it][i] = 0;
			}


	}
};

在这里插入图片描述
思路:如果 s2 为 s1 轮转而成,那么 s2 前一部分和 s1 的后一部分子串相等,s2 的后一部分和 s1 的前一部分子串相等。
使用s1 = “waterbottle”, s2 = "erbottlewat"进行分析就可以定出要截取的长度。

class Solution {
public:
    bool isFlipedString(string s1, string s2) {
        int m = s1.size(), n = s2.size();
        if(m != n) return false;
        if(m == 0) return true;
        for(int i = 0; i < m; i ++){
            if(s1[i] == s2[0]){
                //string类中对==也进行重载了,很方便
                if(s1.substr(0, i) == s2.substr(m - i) && s1.substr(i) == s2.substr(0, m - i))
                    return true;
            }
        }
        return false;
    }
};


在这里插入图片描述

class Solution {
public:
    //双指针
    int kthToLast(ListNode* head, int k) {
        ListNode*first=new ListNode(-1);//哨兵结点
        first->next=head;
        ListNode*p1=head,*p2=head;
        while(k--)
        {
            p1=p1->next;
        }
        while(p1!=NULL)
        {
            p1=p1->next;
            p2=p2->next;
        }
        delete first;
        first=NULL;
        return p2->val;

    }
};

在这里插入图片描述
极其无聊的题目,没有意义。

class Solution {
public:
    void deleteNode(ListNode* node) {
        //无法访问前驱结点,只好把当前结点变为下一节点,然后删除下一节点
        node->val=node->next->val;
        node->next=node->next->next;
        
    }
};

在这里插入图片描述
这题很简单,就是题目的语文水平真是烂的要死。

 //建立两个链表,一个用来存储小于x的值,一个用来存储大于等于x的值,最后将两个链表拼接起来即可;
class Solution {
public:
    ListNode* partition(ListNode* head, int x) {
        ListNode*head1=new ListNode(-1);
        ListNode*head2=new ListNode(-1);
        ListNode*t1=head1,*t2=head2;
        ListNode*t=head;
        while(t!=NULL)
        {
            if(t->val<x)
            {
                t1->next=t;
                t1=t1->next;

                t=t->next;
                
                t1->next=NULL;

            }
            else
            {
                t2->next=t;
                t2=t2->next;
                
                t=t->next;
                
                t2->next=NULL;

            }
        }
        t1->next=head2->next;
        return head1->next;


    }
};

在这里插入图片描述
这题还是挺好的,要考虑的特殊情况比较多,我修改了2次代码才AC。

class Solution {
public:
    ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
        bool carry=false;
        ListNode*t1=l1,*t2=l2;
        ListNode*new_head=new ListNode(-1);
        ListNode*t=new_head;
        while(t1!=NULL||t2!=NULL)
        {
            int sum1=t1==NULL?0:t1->val;
            int sum2=t2==NULL?0:t2->val;
            int sum=sum1+sum2;
            if(carry)
            {
                sum++;
                carry=false;
            }
            
            if(sum>=10)
            {
                carry=true;
                sum-=10;
            }
            t->next=new ListNode(sum);
            t=t->next;
            if(t1!=NULL)
              t1=t1->next;
            if(t2!=NULL)
              t2=t2->next;
        }
       
        if(carry)
        {
            t->next=new ListNode(1);
        }

        return new_head->next;

    }
};

在这里插入图片描述
这题还是挺好的!

class Solution {
public:
    bool isPalindrome(ListNode* head) {
    //先用快慢指针找链表中点,再对后半段链表进行反转,最后比较两个链表是否相同即可
    if(head==NULL||head->next==NULL)return true;//只有1个结点
    ListNode*slow=head,*fast=head;
    
    while(fast!=NULL&&fast->next!=NULL)
    {
        slow=slow->next;
        fast=fast->next->next;
    }
    ListNode*back_new_head=reverseList(slow);

    ListNode*t1=head;
    ListNode*t2=back_new_head;
    while(t2!=NULL)
    {
        if(t1->val!=t2->val)
        return false;

        t1=t1->next;
        t2=t2->next;

    }
    return true;

    }


    ListNode*reverseList(ListNode*head)
    {
        ListNode*prev=NULL;
        ListNode*cur=head;
        while(cur!=NULL)
        {
            ListNode*temp=cur->next;
            cur->next=prev;
            prev=cur;
            cur=temp;
        }
        return prev;


    }
};

在这里插入图片描述

class Solution {
public:
    ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
        ListNode*t1=headA,*t2=headB;
        int len1=0,len2=0;
        while(t1!=NULL)
        {
            len1++;
            t1=t1->next;
        }
        while(t2!=NULL)
        {
            len2++;
            t2=t2->next;
        }
        int diff=abs(len2-len1);
        t1=headA;
        t2=headB;
        if(len1>len2)
        {
            while(diff--)
            {
                t1=t1->next;
            }
            while(t1!=NULL&&t2!=NULL)
            {
                if(t1==t2)
                return t1;
                
                t1=t1->next;
                t2=t2->next;
            }
            return NULL;

        }
        else
        {
             while(diff--)
            {
                t2=t2->next;
            }
            while(t1!=NULL&&t2!=NULL)
            {
                if(t1==t2)
                return t1;
                
                t1=t1->next;
                t2=t2->next;
            }
            return NULL;

        }
    }
};

在这里插入图片描述

/*
1.判断有没有环
2.求出环中的结点个数
从两个指针相遇的结点开始出发,一边继续向前移动一边计数,当再次回到这个结点时,就可以得到环中的结点个数了。
3.找环的入口结点
先定义两个指针p1、p2指向链表头结点,如果环中有n个结点,则指针p1先在链表上向前移动n步,然后两个指针均以每次1步的速度向前移动。当p2与p1相遇时,相遇结点就是入口结点。
*/

class Solution {
public:
    ListNode *detectCycle(ListNode *head) {
        if(head==NULL)return NULL;
        if(head->next==NULL)return NULL;

        //step1
        ListNode*fast=head,*slow=head;
        while(fast!=NULL&&fast->next!=NULL)
        {
            fast=fast->next->next;
            slow=slow->next;
            if(slow==fast)
            break;
        }
        if(slow!=fast)
        return NULL;

        //step2
        int count=1;
        slow=slow->next;
        while(slow!=fast)
        {
            slow=slow->next;
            count++;
        }

        //step3
        slow=head;
        fast=head;
        while(count--)
        {
            fast=fast->next;
        }
        while(slow!=fast)
        {
            slow=slow->next;
            fast=fast->next;
        }

        return slow;



    }
};

在这里插入图片描述

class TripleInOne {
private:
    vector<int> s;
    int stackSize;
    int spointer[3];
public:
    TripleInOne(int stackSize) {//constructor
    s=vector<int>(stackSize*3,0);
    spointer[0]=0 -1;//减1是因为最初栈为空
    spointer[1]=stackSize -1;
    spointer[2]=stackSize*2 -1;
    this->stackSize=stackSize;
    //第0个栈范围[0,stackSize-1]
    //第1个栈范围[stackSize,2*stackSize-1]
    //第2个栈范围[2*stackSize,3*stackSize-1]
    }
    
    void push(int stackNum, int value) {
    if(spointer[stackNum]+1<(stackNum+1)*stackSize)//表示没有溢出
    {
        spointer[stackNum]++;
        s[spointer[stackNum]]=value;
    }

    }
    
    int pop(int stackNum) {
    if(spointer[stackNum]>=stackNum*stackSize)//表示栈不为空
    {
        return s[spointer[stackNum]--];
    }
    else
    {
        return -1;

    }

    }
    
    int peek(int stackNum) {
    if(spointer[stackNum]>=stackNum*stackSize)//表示栈不为空
    {
        
        return s[spointer[stackNum]];
    }
    else
    {
        return -1;

    }

    }
    
    bool isEmpty(int stackNum) {
    if(spointer[stackNum]>=stackNum*stackSize)//表示栈不为空
    {
        
        return false;
    }
    else
    {
        return true;

    }
    }
};

在这里插入图片描述

class MinStack {
//思路:单栈,用pair压栈两个数,一个是正常元素,另一个是目前最小值
private:
    stack<pair<int,int>>s;
public:
    /** initialize your data structure here. */

    MinStack() {

    }
    
    void push(int x) {
    if(s.empty())
    {
        s.push(make_pair(x,x));
    }
    else
    {
       s.push(make_pair(x,min(x,getMin())));
    }
    
    }
    
    void pop() {
    s.pop();
    
    

    }
    
    int top() {
    return s.top().first;

    }
    
    int getMin() {
    return s.top().second;

    }
};

在这里插入图片描述

class StackOfPlates {
private:
    list<stack<int>>ls;
    int sz;//每个栈的最大容量
public:
//双向链表
    StackOfPlates(int cap) {
    sz=cap;

    }
    
    void push(int val) {
    if(!ls.empty()&&ls.back().size()<sz)
    {
        ls.back().push(val);
    }
    else
    {
        stack<int>temp;
        temp.push(val);
        ls.push_back(temp);

    }

    }
    
    int pop() {
    if(sz==0)return -1;
    if(ls.empty())return -1;
    int ans = ls.back().top();
    ls.back().pop();
    if(ls.back().size()==0)
    ls.pop_back();

    return ans;

    }
    
    int popAt(int index) {
    if(sz == 0) return -1;
    if(index >= ls.size()) return -1;
    list<stack<int>>::iterator it = ls.begin();
    while(index --) ++it;
    int ans = it->top();
    it->pop();
    if(it->size() == 0) ls.erase(it);
    return ans;
    }
};

在这里插入图片描述
这种题秒杀。

class MyQueue {
private:
    stack<int>s1;
    stack<int>s2;
public:
    /** Initialize your data structure here. */
    MyQueue() {

    }
    
    /** Push element x to the back of queue. */
    void push(int x) {
        s1.push(x);

    }
    
    /** Removes the element from in front of queue and returns that element. */
    int pop() {
        int res;
        if(!s2.empty())
        {
            res=s2.top();
            s2.pop();
            return res;
        }
        else
        {
            while(!s1.empty())
            {
                s2.push(s1.top());
                s1.pop();
            }
            res=s2.top();
            s2.pop();
            return res;

        }

    }
    
    /** Get the front element. */
    int peek() {
        
        if(!s2.empty())
        {
           
            return s2.top();
        }
        else
        {
            while(!s1.empty())
            {
                s2.push(s1.top());
                s1.pop();
            }
            
            return s2.top();

        }

    }
    
    /** Returns whether the queue is empty. */
    bool empty() {
        return s1.empty()&&s2.empty();

    }
};

在这里插入图片描述

class SortedStack {
public:
	stack<int>s1, s2;//s1是辅助栈
	SortedStack() {

	}

	void push(int val) {
		while (!s2.empty() && val > s2.top())
		{
			s1.push(s2.top());
			s2.pop();
		}
		s2.push(val);

		while (!s1.empty())
		{
			s2.push(s1.top());
			s1.pop();
		}


	}

	void pop() {
		if (!s2.empty())
			s2.pop();

	}

	int peek() {
		if (!s2.empty())
			return s2.top();

		return -1;

	}

	bool isEmpty() {
		return s2.empty();

	}
};

在这里插入图片描述
很简单的题。

class AnimalShelf {
private:
    queue<vector<int>> queue_cat;
    queue<vector<int>> queue_dog;
public:
    AnimalShelf() {

    }
    
    void enqueue(vector<int> animal) {
        if(animal[1]==0)//是猫
        {
            queue_cat.push(animal);
        }
        else
        {
            queue_dog.push(animal);
        }

    }
    
    vector<int> dequeueAny() {
        vector<int>temp;
        if(queue_cat.empty()&&queue_dog.empty())
        {
            return {-1,-1};
        }
        else if(!queue_cat.empty()&&queue_dog.empty())
        {
            temp=queue_cat.front();
            queue_cat.pop();
        }
        else if(queue_cat.empty()&&!queue_dog.empty())
        {
            temp=queue_dog.front();
            queue_dog.pop();
        }
        else
        {
            if((queue_cat.front())[0]<(queue_dog.front())[0])//动物编号:猫 < 狗 猫先出
            {
                temp=queue_cat.front();
                queue_cat.pop();
            }
            else
            {
                temp=queue_dog.front();
                queue_dog.pop();
            }

        }

        return temp;

    }
    
    vector<int> dequeueDog() {
        vector<int>temp;
        if(queue_dog.empty())
        {
            return {-1,-1};
        }
        else
        {
            temp=queue_dog.front();
            queue_dog.pop();
            return temp;

        }

    }
    
    vector<int> dequeueCat() {
        vector<int>temp;
        if(queue_cat.empty())
        {
            return {-1,-1};
        }
        else
        {
            temp=queue_cat.front();
            queue_cat.pop();
            return temp;

        }

    }
};


在这里插入图片描述
非常经典的题!考查图的遍历DFS或BFS
法1.DFS

class Solution {
    vector<bool> visited;
    vector<vector<int>> adList;
public:
    bool findWhetherExistsPath(int n, vector<vector<int>>& graph, int start, int target) {
        visited = vector<bool>(n,0);
        adList = vector(n,vector<int>());
        for (int i=0;i<graph.size();i++)
		{
            adList[graph[i][0]].push_back(graph[i][1]);//表示i-->adList[i][j]
        }
        return DFS(start,target);
    }

    bool DFS(int start,int target)
	{
        visited[start] = true;
        bool result = false;
        for(int i=0;i<adList[start].size();i++)
		{
            if (visited[adList[start][i]]==false)
			{
                if(adList[start][i]==target)
				{
                    visited[adList[start][i]] =true;
                    return true;
                }
                result = DFS(adList[start][i],target);//完成后续递归
                if(result==true)
                   return true;
            }
        }
		
        return false;
    }
};


法2:BFS

class Solution {
	vector<bool> visited;
	vector<vector<int>> adList;
public:
	bool findWhetherExistsPath(int n, vector<vector<int>>& graph, int start, int target) {
		visited = vector<bool>(n, 0);
		adList = vector(n, vector<int>());
		for (int i = 0; i < graph.size(); i++)
		{
			adList[graph[i][0]].push_back(graph[i][1]);//表示i-->adList[i][j]
		}
		return BFS(start, target);
	}

	bool BFS(int start, int target)
	{
		queue<int> q;
		int temp;
		visited[start] = true;
		q.push(start);
		while (!q.empty())
		{
			temp = q.front();
			q.pop();
			for (int i = 0; i < adList[temp].size(); i++)
			{
				if (visited[adList[temp][i]] == false)
				{
					visited[adList[temp][i]] = true;
					if (adList[temp][i] == target)
					{
						return true;
					}
					else
					{
						q.push(adList[temp][i]);
					}
				}
			}
		}
		return 0;

	}
};

在这里插入图片描述
简单的递归:

class Solution {
public:
    TreeNode* sortedArrayToBST(vector<int>& nums) {
        if(nums.size()==0)return NULL;
        return DFS(nums,0,nums.size()-1);
        

    }
    TreeNode*DFS(vector<int>&nums,int low,int high)
    {
        if(low>high)
        {
            return NULL;
        }
        int mid=(low+high)/2;
        TreeNode*root=new TreeNode(nums[mid]);
        root->left=DFS(nums,low,mid-1);
        root->right=DFS(nums,mid+1,high);
        return root;

    }
};

在这里插入图片描述
简单的BFS,秒杀

class Solution {
private:
    vector<ListNode*>res;
    queue<TreeNode*>myqueue;
public:
//简单的BFS
    vector<ListNode*> listOfDepth(TreeNode* tree) {

        if(tree==NULL)return{};
        myqueue.push(tree);
        BFS();
        return res;


    }
    void BFS()
    {
        while(!myqueue.empty())
        {

            int size=myqueue.size();

            ListNode*dummy=new ListNode(-1);
            ListNode*cur=dummy;
            for(int i=0;i<size;i++)
            {
                TreeNode*temp=myqueue.front();
                myqueue.pop();
                cur->next=new ListNode(temp->val);
                cur=cur->next;
                if(temp->left!=NULL)
                {
                    myqueue.push(temp->left);
                }
                if(temp->right!=NULL)
                {
                    myqueue.push(temp->right);
                }
            }
            res.push_back(dummy->next);

        }

    }
};

在这里插入图片描述
秒杀

//简单的DFS
class Solution {
public:
    bool isBalanced(TreeNode* root) {
       if(root==NULL)return true;
       if(abs(depth(root->left)-depth(root->right))>1)return false;

       return isBalanced(root->left)&&isBalanced(root->right);


    }
    int depth(TreeNode*root)
    {
        if(root==NULL)
        {
            return 0; 
        }
        return max(depth(root->left),depth(root->right))+1;
    }
};

在这里插入图片描述
DFS,中序遍历

class Solution {
private:
	long pre = LONG_MIN;
public:
	bool isValidBST(TreeNode* root) {
		if (!root)
			return true;
		if (!isValidBST(root->left))//左子树已经完成判断
			return false;

		if (root->val <= pre)
			return false;
		pre = root->val;

        
		return isValidBST(root->right);//右子树已经完成判断
	}
};

在这里插入图片描述

法1:开一个数组直接保存中序遍历序列,然后再慢慢找

class Solution {
private:
    vector<TreeNode*>res;
public:
    TreeNode* inorderSuccessor(TreeNode* root, TreeNode* p) {
        DFS(root);
        res.push_back(NULL);
        for(int i=0;i+1<res.size();i++)
        {
            if(p==res[i])
            return res[i+1];
        }
        return NULL;
       
    }
    void DFS(TreeNode*root)
    {
        if(root==NULL)
        return;
        DFS(root->left);

        res.push_back(root);

        DFS(root->right);
    }
};

法2:漂亮的DFS,,利用BST的特性,一步到位

class Solution {
public:
    TreeNode* inorderSuccessor(TreeNode* root, TreeNode* p) {
        if (root == NULL || p == NULL) return NULL;
        if (p->val >= root->val)
        {
            return inorderSuccessor(root->right, p);//要找的目标结点一定在右子树中

        } else //要找的目标结点在左子树中,或者目标结点就是根结点
        {
            TreeNode*left = inorderSuccessor(root->left, p);
            return left ? left : root;
        }
    }
};

在这里插入图片描述
这题是非常好的递归题!!
当我们用递归去做这个题时不要被题目误导,应该要明确一点
这个函数的功能有三个:给定两个节点p和q
1.如果p和q都存在,则返回它们的公共祖先;
2.如果只存在一个,则返回存在的一个;
3.如果p和q都不存在,则返回NULL;

class Solution {
public:
	TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {

		if (root == NULL)return NULL;
		if (root == p || root == q)
			return root;

		TreeNode*left = lowestCommonAncestor(root->left, p, q);//假设已经完成
		TreeNode*right = lowestCommonAncestor(root->right, p, q);//假设已经完成
		if (left == NULL)//说明p、q都在右子树
			return right;
		if (right == NULL)//说明p、q都在左子树
			return left;
		if (left&&right)//说明p、q一个在左子树,另一个在右子树
			return root;

		return NULL;
	}
};

在这里插入图片描述

class Solution {
public:
    bool checkSubTree(TreeNode* t1, TreeNode* t2) {
        if(t1==NULL&&t2==NULL)return true;
        if(t1==NULL&&t2!=NULL)return false;
        
        return isSametree(t1,t2)
        || checkSubTree(t1->left,t2)||checkSubTree(t1->right,t2);
    }
    bool isSametree(TreeNode* t1, TreeNode* t2)
    {
        if(t1==NULL&&t2==NULL)return true;
        if(t1==NULL||t2==NULL)return false;
        return t1->val==t2->val&&isSametree(t1->left,t2->left)&&isSametree(t1->right,t2->right);


    }
};

在这里插入图片描述
经典的双递归题。

class Solution {
private:
	vector<int>cur;
	vector<vector<int>>res;
public:
    int pathSum(TreeNode* root, int sum) {
        if(root==NULL)return 0;
        DFS_2(root,sum);
        return res.size();

    }
    void DFS_1(TreeNode*root,int sum)//以root为根结点开始找
    {
        if(root==NULL)return;
        cur.push_back(root->val);

        if(sum-root->val==0)
        {
            res.push_back(cur);
        }
        DFS_1(root->left,sum-root->val);
        DFS_1(root->right,sum-root->val);

        cur.pop_back();

    }
    void DFS_2(TreeNode*root,int sum)//对每一个结点都当作根结点试一试
    {
        if(root==NULL)return;
        DFS_1(root,sum);
        

        DFS_2(root->left,sum);
        DFS_2(root->right,sum);
    }
};

在这里插入图片描述

class Solution {
public:
//1.把 N 中 i~j 的位置先置零
//2.把 M 左移 i 位后和 N 相加
    int insertBits(int N, int M, int i, int j) {
        int t=0;
        for(int x=i;x<=j;x++)
        {
            t|=(1<<x);//把i~j 的位置先置1
        }
        t=~t;
        N&=t;
        M<<=i;
        return M+N;
    }
};

在这里插入图片描述

在这里插入图片描述

class Solution {
public:
    string printBin(double num) {
        string res = "0.";
        int i = 30; // 因为题中要求用32位以内的二进制表示,所以 "0." 计为两位,所以把i初始化为30
        while (num > 0. && i--) {
            num *= 2;
            if (num >= 1) {
                res.push_back('1');
                --num;
            }
            else res.push_back('0');
        }
        return num != 0. ? "ERROR" : res;
    }
};

在这里插入图片描述
挺好的题,思路我觉得很不错!

class Solution {
public:
    int reverseBits(int num) {
        int res=0;
        int cur=0,prev=0;
        //从低位开始
        while(num)
        {
            if(num&1)
            {
                cur++;
            }
            else//当前bit是0
            {
                if(cur+prev+1>res)
                {
                    res=cur+prev+1;
                }
                prev=cur;
                cur=0;
            }
            num>>=1;
        }

        //别忘记最后还需要额外判断一次

        if(cur+prev+1>res)
        {
            res=cur+prev+1;
        }
        return res;

    }
};

在这里插入图片描述
显然,这题唯一需要注意的就是负数的右移情况

class Solution {
public:
    int convertInteger(int A, int B) 
    {
        return convertInteger((unsigned int)A,(unsigned int)B);

    }
    int convertInteger(unsigned int A, unsigned int B) {
        int t1,t2;
        int count=0;
        while(A||B)
        {
            
            t1=A&1;
            t2=B&1;
            if(t1!=t2)
              count++;
            A>>=1;
            B>>=1;

        }
        return count;

    }
};

在这里插入图片描述
经典的位运算题目!

//运算时的转换
//当运算涉及两种类型时,较小的类型将会被转换为较大的类型,也就是表达力低的类型会被转换为表达力高的类型。
//各类型表达能力从低到高排列为:
//int-->unsigned int-->long-->unsigned long-->float-->double-->long double

class Solution {
public:
    int exchangeBits(int num) {
        return ((num&0xaaaaaaaa)>>1) | ((num&0x55555555)<<1);
        //提取奇数位,并右移1位到偶数位置,注意,0xaaaaaaaa的类型是unsigned int,所以int&unsigned int运算时,先把int提升为unsigned int,然后unsigned int&unsigned int。而unsigned int进行右移操作是不会有问题的,高位会补0
        //提取偶数位,并左移1位到奇数位置

    }
};

猜你喜欢

转载自blog.csdn.net/ShenHang_/article/details/106979522