力扣OJ 面试题

目录

面试题 04.05. 合法二叉搜索树

面试题 05.04. 下一个数

面试题 05.08. 绘制直线

面试题 30. 包含min函数的栈

面试题 34. 二叉树中和为某一值的路径


面试题 04.05. 合法二叉搜索树

二叉搜索树 https://blog.csdn.net/nameofcsdn/article/details/114281344

面试题 05.04. 下一个数

下一个数。给定一个正整数,找出与其二进制表达式中1的个数相同且大小最接近的那两个数(一个略大,一个略小)。

示例1:

 输入:num = 2(或者0b10)
 输出:[4, 1] 或者([0b100, 0b1])
示例2:

扫描二维码关注公众号,回复: 12915145 查看本文章

 输入:num = 1
 输出:[2, -1]
提示:

num的范围在[1, 2147483647]之间;
如果找不到前一个或者后一个满足条件的正数,那么输出 -1。

itoa和atoi都是直接百度复制的,nextGreaterElement函数是从我另外一个题目代码复制过来略改的

https://blog.csdn.net/nameofcsdn/article/details/106915634

只需要改2个地方,一个是整数转化为二进制字符串,一个是二进制字符串转化为整数。

nextLesserElement函数是nextGreaterElement函数直接修改得到,代码逻辑是一样的。
 

char* itoa(int num,char* str,int radix)  //copy from 百度百科
{/*索引表*/
    char index[]="0123456789ABCDEF";
    unsigned unum;/*中间变量*/
    int i=0,j,k;
    /*确定unum的值*/
    if(radix==10&&num<0)/*十进制负数*/
    {
        unum=(unsigned)-num;
        str[i++]='-';
    }
    else unum=(unsigned)num;/*其他情况*/
    /*转换*/
    do{
        str[i++]=index[unum%(unsigned)radix];
        unum/=radix;
       }while(unum);
    str[i]='\0';
    /*逆序*/
    if(str[0]=='-')
        k=1;/*十进制负数*/
    else
        k=0;
     
    for(j=k;j<=(i-1)/2;j++)
    {       char temp;
        temp=str[j];
        str[j]=str[i-1+k-j];
        str[i-1+k-j]=temp;
    }
    return str;
}
int atoi2(const char *nptr)
{
        int c;              /* current char */
        int total;         /* current total */
        int sign;           /* if '-', then negative, otherwise positive */
 
        /* skip whitespace */
        while ( isspace((int)(unsigned char)*nptr) )
            ++nptr;
 
        c = (int)(unsigned char)*nptr++;
        sign = c;           /* save sign indication */
        if (c == '-' || c == '+')
            c = (int)(unsigned char)*nptr++;    /* skip sign */
 
        total = 0;
 
        while (isdigit(c)) {
            total = 2 * total + (c - '0');     /* accumulate digit */
            c = (int)(unsigned char)*nptr++;    /* get next char */
        }
 
        if (sign == '-')
            return -total;
        else
            return total;   /* return result, negated if necessary */
}
int nextGreaterElement(int n) {
        char sn[40];
        for(int i=0;i<32;i++)sn[i]=((n&(1<<31-i))?'1':'0');
        sn[32]='\0';
        int len=strlen(sn);
        for(int i=len-2;i>=0;i--)
        {
            if(sn[i]>=sn[i+1])continue;
            for(int j=len-1;j>i;j--)
            {
                if(sn[i]>=sn[j])continue;                
                sn[j]^=sn[i]^=sn[j]^=sn[i];
                sort(sn+i+1,sn+len);
                long long res = atoi2(sn);
                if(res==int(res))return res;
                return -1;
            }
        }
        return -1;
    }
int nextLesserElement(int n) {
        char sn[40];
        for(int i=0;i<32;i++)sn[i]=((n&(1<<31-i))?'1':'0');
        sn[32]='\0';
        int len=strlen(sn);
        for(int i=len-2;i>=0;i--)
        {
            if(sn[i]<=sn[i+1])continue;
            for(int j=len-1;j>i;j--)
            {
                if(sn[i]<=sn[j])continue;                
                sn[j]^=sn[i]^=sn[j]^=sn[i];
                sort(sn+i+1,sn+len,greater<char>());
                long long res = atoi2(sn);
                if(res==int(res))return res;
                return -1;
            }
        }
        return -1;
    }
class Solution {
public:
    vector<int> findClosedNumbers(int num) {
        vector<int> ans(2);
        ans[1]=nextLesserElement(num);
        ans[0]=nextGreaterElement(num);
        return ans;
    }
};

后来发现可以用c++的库函数获取上一个下一个全排列,就更简单了

//把整数转化为字符串
char* itoa(int num,char* str,int radix)  //copy from 百度百科
{/*索引表*/
    char index[]="0123456789ABCDEF";
    unsigned unum;/*中间变量*/
    int i=0,j,k;
    /*确定unum的值*/
    if(radix==10&&num<0)/*十进制负数*/
    {
        unum=(unsigned)-num;
        str[i++]='-';
    }
    else unum=(unsigned)num;/*其他情况*/
    /*转换*/
    do{
        str[i++]=index[unum%(unsigned)radix];
        unum/=radix;
       }while(unum);
    str[i]='\0';
    /*逆序*/
    if(str[0]=='-') k=1;/*十进制负数*/
    else k=0;     
    for(j=k;j<=(i-1)/2;j++)
    {   
        char temp;
        temp=str[j];
        str[j]=str[i-1+k-j];
        str[i-1+k-j]=temp;
    }
    return str;
}
//把字符串转化为整数
long long atoi(const char *nptr,int radix) //copy from somebody
{        
        while ( isspace((int)(unsigned char)*nptr) )  ++nptr;/* skip whitespace */
        int c = (int)(unsigned char)*nptr++;
        int sign = c;           /* save sign indication */
        if (c == '-' || c == '+')  c = (int)(unsigned char)*nptr++;    /* skip sign */
        long long total = 0;
        while (isdigit(c)) {
            total = radix * total + (c - '0');     /* accumulate digit */
            c = (int)(unsigned char)*nptr++;    /* get next char */
        }
        if (sign == '-')   return -total;
        else  return total;   /* return result, negated if necessary */
}
int nextGreaterElement(int n) {
        char sn[40];
        for(int i=0;i<32;i++)sn[i]=((n&(1<<31-i))?'1':'0');
        sn[32]='\0';
        next_permutation(sn,sn+32);        
        long long res = atoi(sn,2);
        if(res==int(res))return res;
        return -1;
}
int nextLesserElement(int n) {
        char sn[40];
        for(int i=0;i<32;i++)sn[i]=((n&(1<<31-i))?'1':'0');
        sn[32]='\0';
        prev_permutation(sn,sn+32);        
        long long res = atoi(sn,2);
        if(res==int(res))return res;
        return -1;
}
class Solution {
public:
    vector<int> findClosedNumbers(int num) {
        vector<int> ans(2);
        ans[1]=nextLesserElement(num);
        ans[0]=nextGreaterElement(num);
        return ans;
    }
};

面试题 05.08. 绘制直线

题目:

绘制直线。有个单色屏幕存储在一个一维数组中,使得32个连续像素可以存放在一个 int 里。屏幕宽度为w,且w可被32整除(即一个 int 不会分布在两行上),屏幕高度可由数组长度及屏幕宽度推算得出。请实现一个函数,绘制从点(x1, y)到点(x2, y)的水平线。

给出数组的长度 length,宽度 w(以比特为单位)、直线开始位置 x1(比特为单位)、直线结束位置 x2(比特为单位)、直线所在行数 y。返回绘制过后的数组。

示例1:

 输入:length = 1, w = 32, x1 = 30, x2 = 31, y = 0
 输出:[3]
 说明:在第0行的第30位到第31为画一条直线,屏幕表示为[0b000000000000000000000000000000011]
示例2:

 输入:length = 3, w = 96, x1 = 0, x2 = 95, y = 0
 输出:[-1, -1, -1]

代码:
 

class Solution {
public:
    vector<int> drawLine(int length, int w, int x1, int x2, int y) {
        vector<int>ans;
        int s=x1/32+w/32*y,e=x2/32+w/32*y;
        for(int i=0;i<s;i++)ans.insert(ans.end(),0);
        for(int i=s;i<=e;i++)ans.insert(ans.end(),-1);
        for(int i=e+1;i<length;i++)ans.insert(ans.end(),0);
        x1=32-x1%32,x2=31-x2%32;
        long long a=1;
        ans[s]&=int((a<<x1)-1),ans[e]&=(-(1<<x2));
        return ans;
    }
};

面试题 30. 包含min函数的栈

定义栈的数据结构,请在该类型中实现一个能够得到栈的最小元素的 min 函数在该栈中,调用 min、push 及 pop 的时间复杂度都是 O(1)。

示例:

MinStack minStack = new MinStack();
minStack.push(-2);
minStack.push(0);
minStack.push(-3);
minStack.min();   --> 返回 -3.
minStack.pop();
minStack.top();      --> 返回 0.
minStack.min();   --> 返回 -2.
 

提示:

各函数的调用总次数不超过 20000 次

class MinStack {
public:
    stack<int>s;//主栈
    stack<int>m;//单调栈
 
    MinStack() {
    }
    
    void push(int x) {
        s.push(x);
        if(m.empty()||m.top()>=x)m.push(x);
    }
    
    void pop() {
        if(m.top()==s.top())m.pop();
        s.pop();        
    }
    
    int top() {
        return s.top();
    }
    
    int min() {
        return m.top();
    }
};

面试题 34. 二叉树中和为某一值的路径

题目:

给定一个二叉树和一个目标和,找到所有从根节点到叶子节点路径总和等于给定目标和的路径。

说明: 叶子节点是指没有子节点的节点。

示例:
给定如下二叉树,以及目标和 sum = 22,

              5
             / \
            4   8
           /   / \
          11  13  4
         /  \    / \
        7    2  5   1
返回:

[
   [5,4,11,2],
   [5,8,4,5]
]

代码:

​
class Solution {
public:
	vector<vector<int>> pathSum(TreeNode* root, int sum) {
		vector<int>tmp;
		vector<vector<int>>ans;
		if (!root)return ans;
		if (!root->left && !root->right)
		{
			if (sum == root->val)
			{
				tmp.insert(tmp.end(), sum);
				ans.insert(ans.end(), tmp);
			}
			return ans;
		}
		ans = pathSum(root->left, sum - root->val);
		vector<vector<int>>ans2 = pathSum(root->right, sum - root->val);
		for (int i = 0; i < ans2.size(); i++)
		{
			ans.insert(ans.end(), ans2[i]);
		}
		for (int i = 0; i < ans.size(); i++)
		{
			ans[i].insert(ans[i].begin(), root->val);
		}
		return ans;
	}
};

​
 

猜你喜欢

转载自blog.csdn.net/nameofcsdn/article/details/115095135