刷题笔记(下)---由浅入深

本篇主要是介绍一些笔试中常用的算法。



文章目录

  • 一、二叉树的后序遍历序列
  • 二、二叉树中和为某一值的路径(二)
  • 三、字符串的排列
  • 四、最下的K个数
  • 五、连续子数组的最大和
  • 六、回文数索引
  • 七、把数组排成最下的数
  • 八、两个链表的第一个公共结点
  • 九、二叉树的深度
  • 十、数组中只出现一次的数字
  • 十一、和为S的连续正数序列
  • 十二、左旋转字符串
  • 十三、翻转单词序列
  • 十四、按之字形顺序打印二叉树
  • 十五、二叉搜索树的第k个结点


一、二叉搜索树的后序遍历序列OJ链接

class Solution {
public:
    bool VerifySquenOfBSTHelper(vector<int> sequence,int start, int end)
    {
        //如果此时start比end大说明此时满足二叉搜索树的条件
        if(start>=end)
        return true;
        int root=sequence[end];//根节点为为遍历数组序列的最后一个元素
        int i=start;
        while(i<=end&&sequence[i]<root)//查找二叉树中左子树中是否是满足左子树是小于根节点的条件
        {
            i++;
        }
        //查找二叉树中右子树是否是满足右子树是大于根节点的条件,如果不满足,则直接返回false
        for(int j=i;j<end;j++)
        {
            if(sequence[j]<root)
            return false;
        }
        return VerifySquenOfBSTHelper(sequence,start,i-1)&&VerifySquenOfBSTHelper(sequence,i,end-1);
    }
    
    bool VerifySquenceOfBST(vector<int> sequence) {
        //前提条件:如果此时所给的后序遍历数组为空则直接返回false
        if(sequence.empty())
        return false;
        //如果不为空,则进行将后序遍历序列进行分序查找
        return VerifySquenOfBSTHelper(sequence,0,sequence.size()-1);
        
    }
};

二、二叉树中和为某一值的路径(二)OJ链接

/*
struct TreeNode {
	int val;
	struct TreeNode *left;
	struct TreeNode *right;
	TreeNode(int x) :
			val(x), left(NULL), right(NULL) {
	}
};*/
class Solution {
public:
    void FindPathDFS(TreeNode*root,int expectNumber,vector<vector<int>>&result,vector<int>&list)
	{
		if(root==nullptr)
		return;
		//先进行添加值
		list.push_back(root->val);
		expectNumber-=root->val;
		//将现有结果进行判断
		if(expectNumber==0&&root->left==nullptr&&root->right==nullptr)
		{
			result.push_back(list);
		}
		//进行深度搜索
		FindPathDFS(root->left,expectNumber,result,list);
		FindPathDFS(root->right,expectNumber,result,list);
		//回退
		list.pop_back();
	}
    vector<vector<int>> FindPath(TreeNode* root,int expectNumber) {
        vector<vector<int>> result;
		vector<int> list;
		if(root==nullptr)
		return result;
		FindPathDFS(root,expectNumber,result,list);
		return result;//返回结果集

    }
};

三、字符串的排列OJ链接

class Solution {
public:
    vector<string> Permutation(string str) {
        vector<string> result;
        sort(str.begin(),str.end());//首先利用sort进行排序
        do
        {
            result.push_back(str);
        }while(next_permutation(str.begin(),str.end()));//利用STL中的next_permutation进行全排列
        return result;
    }
};

四、最小K个数OJ链接

class Solution {
public:
    vector<int> GetLeastNumbers_Solution(vector<int> input, int k) {
         vector<int> result;
        if(input.size()==0||k==0)
        return result;
       
        priority_queue<int,vector<int>> q;//利用大根堆的方式进行
        for(int i=0;i<input.size();i++)
        {
            if(i<k)//将前面4个元素放入堆中
            q.push(input[i]);
            else
            {
                if(input[i]<q.top())//如果此时堆顶的数据比下一个大则出堆
                {
                    q.pop();
                    q.push(input[i]);
                }
            }
        }
        //需要将最后堆中的数据放入数组中
        for(int i=0;i<k;i++)
        {
            result.push_back(q.top());
            q.pop();
        }
        return result;
    }
};

五、连续子数组的最大和OJ链接

class Solution {
public:
    int FindGreatestSumOfSubArray(vector<int> array) {
        if(array.size()==0)//如果此时数组中无元素则返回0
        return 0;
        //子状态:f(i)中连续子数组和最大
        //状态间的转移方程:dp[i]=max(dp[i-1]+array[i],array[i]);
        //初始化:dp[0]=array[0];max_value=array[0];
        //返回max_value;
        vector<int> dp;
        dp.resize(array.size(),0);
        int max_value=array[0];
        dp[0]=array[0];
        for(int i=1;i<array.size();i++)
        {
            dp[i]=max(dp[i-1]+array[i],array[i]);
            if(max_value<dp[i])
            max_value=dp[i];
        }
        return max_value;
    }
};

六、回文数索引 OJ链接 

#include<bits/stdc++.h>
using namespace std;
bool  IsPalindrome(string &s,int*start,int *end)
{
    int i=0;
    int j=s.size()-1;
    bool result=true;
    while(i<=j)
    {
        if(s[i]!=s[j])
        {
           result=false;
           break;
        }
        i++;
        j--;
    }
    if(start!=nullptr)//定位此时不是回文串的位置
    {
        *start=i;
    }
    if(end!=nullptr)
    {
        *end=j;
    }
    return result;
}
int main()
{
    int n;
    cin>>n;
    while(n--)
    {
        string str;
        cin>>str;
        int start=0;
        int end=str.size()-1;
        if(IsPalindrome(str,&start,&end))
        {
            cout<<"-1"<<endl;
        }
        else
        {
            str.erase(end,1);
            if(IsPalindrome(str,nullptr,nullptr))//判断是否是回文如果是回文,则删除位置后为回文串,反之如果不是则说明删除start是回文串
            {
                cout<<end<<endl;
            }
            else
            {
                cout<<start<<endl;
            }

        }

    }
    return 0;

}

七、把数组排成最小的数OJ链接

class Solution {
public:
    static bool cmp(int x,int y)
    {
        string a=to_string(x);
        string b=to_string(y);
        return a+b<b+a;
    }
    string PrintMinNumber(vector<int> numbers) {
        //利用sort将小的放到前面
        sort(numbers.begin(),numbers.end(),cmp);
        string result;
        for(int i=0;i<numbers.size();i++)
        {
            result+=to_string(numbers[i]);
        }
        return result;
    }
};

八、两个链表的第一个公共结点OJ链接

/*
struct ListNode {
	int val;
	struct ListNode *next;
	ListNode(int x) :
			val(x), next(NULL) {
	}
};*/
class Solution {
public:
    //求出两个链表的长度,让长的链表走差距步,再同步走
    int GetListLength(ListNode*head)
	{
		int length=0;
		ListNode*cur=head;
		while(cur)
		{
			length++;
			cur=cur->next;
		}
		return length;
	}
    ListNode* FindFirstCommonNode( ListNode* pHead1, ListNode* pHead2) {
		int pHead1Length=0;
		int pHead2Length=0;
		pHead1Length=GetListLength(pHead1);
		pHead2Length=GetListLength(pHead2);
		int gap;
		if(pHead1Length>pHead2Length)
		{
			gap=pHead1Length-pHead2Length;
			while(gap--)
		    {
			pHead1=pHead1->next;
		    }
		}
		else
		{
			gap=pHead2Length-pHead1Length;
			while(gap--)
		    {
			pHead2=pHead2->next;
		     }
		}
		while(pHead1&&pHead2)
		{
			if(pHead1==pHead2)
			return pHead1;
			pHead1=pHead1->next;
			pHead2=pHead2->next;
		}
		return nullptr;
    }
};

九、二叉树的深度OJ链接

/*
struct TreeNode {
	int val;
	struct TreeNode *left;
	struct TreeNode *right;
	TreeNode(int x) :
			val(x), left(NULL), right(NULL) {
	}
};*/
class Solution {
public:
    // void TreeDepthHelper(TreeNode*pRoot,int cur,int&max)
	// {
	// 	if(pRoot==nullptr)//如果此时为空则将此时所到达的深度与max进行比较如果比大的话更新max,返回
	// 	{
	// 		if(max<cur)
	// 		{
	// 			max=cur;
	// 		}
	// 		return;
	// 	}
	// 	TreeDepthHelper(pRoot->left,cur+1,max);
	// 	TreeDepthHelper(pRoot->right,cur+1,max);
	// }
    int TreeDepth(TreeNode* pRoot) {
		//利用递归的思路进行深度遍历
	// 	if(pRoot==nullptr)
	// 	return 0;
	// 	return 1+max(TreeDepth(pRoot->left),TreeDepth(pRoot->right));
    // }








	// if(pRoot==nullptr)
	// return 0;
	// int depth=0;
	// int max=0;
	// TreeDepthHelper(pRoot,depth,max);
	// return max;
	//利用队列的特点进行层序遍历
      if(pRoot==nullptr)
	  {
		  return 0;
	  }
	  queue<TreeNode*> q;
	  q.push(pRoot);
	  int depth=0;
	  while(!q.empty())
	  {
		  depth++;
		  for(int i=0;i<q.size();i++)
		  {
			  TreeNode*front=q.front();
			  q.pop();
			  if(front->left)
			  {
				  q.push(front->left);
			  }
			  if(front->right)
			  {
				  q.push(front->right);
			  }
		  }
	  }
	  return depth;




	}
};

十、数组中只出现一次数字OJ链接

class Solution {
public:
    void FindNumsAppearOnce(vector<int> data,int* num1,int *num2) {
        //利用哈希的方式进行遍历
        unordered_map<int,int> hashTable;
        vector<int> v;
        for(int i=0;i<data.size();i++)
        {
            hashTable[data[i]]++;
        }
        for(int i=0;i<data.size();i++)
        {
            if(hashTable[data[i]]==1)
            {
                v.push_back(data[i]);
            }
        }
        *num1=v[0];
        *num2=v[1];
    }
};

十一、和为S的连续正数序列OJ链接

class Solution {
public:
    vector<vector<int> > FindContinuousSequence(int sum) {
        vector<vector<int>> result;//保留连续的正序列和
        int low=1;
        int high=2;
        while(low<high)//low到high这个区间中的数相加是否是等于sum
        {
            int total=(low+high)*(high-low+1)/2;//利用等差数列的求和公式求出和
            if(sum==total)//如果此时是100则需要将此时的low往后移动查找是否还有这样的序列
            {
                vector<int> v;
                for(int i=low;i<=high;i++)
                {
                    v.push_back(i);
                }
                result.push_back(v);
                low++;
            }
            else if(total<sum)//如果区间总数没有达到所给的sum需要将high往后移动
            {
                high++;
            }
            else//如果此时区间总数达到了所给的sum需要就爱那个low+往后移动
            {
                low++;
            }
        }
        return result;
    }
};

十二、左旋转字符串OJ链接

class Solution {
public:
    void LeftRotateStringHelper(string &str)//将首元素保存每一次旋转之后将首元素放在旋转之后的字符串后面
    {
        char temp=str[0];
        int i=0;
        for(i=0;i<str.size()-1;i++)
        {
            str[i]=str[i+1];
        }
        str[i]=temp;
    }
    string LeftRotateString(string str, int n) {
        // if(str.empty())//如果此时为空直接返回空串
        // return str;
        // n%=str.size();//该步骤就是为了确保循环的次数是在10之内的次数
        // reverse(str.begin(),str.end()-(str.size()-n));//将前n个字符进行反转
        // reverse(str.begin()+n,str.end());//后面的字符进行反转
        // reverse(str.begin(),str.end());//最后将所有的字符进行反转
        // return str;




        //利用暴力的方式进行求解
        if(str.empty())
        return str;
        n%=str.size();
        while(n--)
        {
            LeftRotateStringHelper(str);
        }
        return str;
    }
};

十三、翻转单词序列OJ链接

class Solution {
public:
    string ReverseSentence(string str) {
        if(str.empty())
        return str;
        int i=0;
        int j=0;
        while(j<str.size())
        {
            if(isspace(str[j]))//如果此时为空需要将空格之前的单词进行反转操作同时需要更新i,j
            {
                reverse(str.begin()+i,str.begin()+j);
                j++;
                i=j;
            }//如果此时不为空格,j往后移动寻找空格
            else
            {
                j++;
            }
        }
        //需要将最后一个单词进行反转操作
        reverse(str.begin()+i,str.begin()+j);
        //最后需要将整体进行反转操作
        reverse(str.begin(),str.end());
        return str;
    }
};

十四、按之字形顺序打印二叉树OJ链接


/*
struct TreeNode {
    int val;
    struct TreeNode *left;
    struct TreeNode *right;
    TreeNode(int x) :
            val(x), left(NULL), right(NULL) {
    }
};
*/
class Solution {
public:
    vector<vector<int> > Print(TreeNode* pRoot) {
        vector<vector<int> > result;
    if(pRoot == nullptr){
    return result;
    }
    stack<TreeNode*> st; //保存要遍历的节点
    queue<TreeNode*> q; //作为临时队列来进行辅助,stack不能既用来出,有用来进
    st.push(pRoot);
    int dir = 1; //1. 入栈顺序从left开始. 2.入栈顺序从right开始.
    vector<int> v;
    while(!st.empty()){
    int size = st.size();
    for(int i = 0; i < size; i++){ //清空本轮stack结构,并遍历,stack本身有逆序的功能
    TreeNode *curr = st.top();
    st.pop();
    v.push_back(curr->val);
    TreeNode *first = (dir == 1)?curr->left:curr->right;
    TreeNode *second = (dir == 1)?curr->right:curr->left;
    //将下一轮访问顺序放入q中
    if(first != nullptr)
     q.push(first);
    if(second != nullptr) 
    q.push(second);
    }
    //将本层符合要求的所有节点,入result
    result.push_back(v);
    //将下一轮访问节点入栈,进行逆序
    while(!q.empty()){
    st.push(q.front());
    q.pop();
    }
    //一层遍历完毕,就要更改入栈顺序
    dir = (dir == 1)? 2 : 1;
    v.clear();
    }
    return result;
    }
    
};

十五、二叉搜索树的第k个结点OJ链接

 

/**
 * struct TreeNode {
 *	int val;
 *	struct TreeNode *left;
 *	struct TreeNode *right;
 *	TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 * };
 */
class Solution {
public:
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param proot TreeNode类 
     * @param k int整型 
     * @return int整型
     */
    int KthNode(TreeNode* proot, int k) {
        // write code here
        if(proot==nullptr||k==0)
        return -1;
        stack<TreeNode*> ST;
        TreeNode*node=proot;
        do
        {
            while(node!=nullptr)//将左子树入栈
            {
                ST.push(node);
                node=node->left;
            }
            if(!ST.empty())//如果栈不为空的话
            {
                node=ST.top();//将栈顶元素
                ST.pop();//将栈顶元素进行出栈
                k--;//
                if(k==0)//如果此时是第k个结点直接返回
                return node->val;
            }
            node=node->right;//判断右子树
        }while(node!=nullptr||!ST.empty());
       return -1;
    }
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

‘(尐儍苽-℡

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值