编程题记录

1.给出一个字符串 A, 表示一个 n 位正整数, 删除其中 k 位数字, 使得剩余的数字仍然按照原来的顺序排列产生一个新的正整数。

找到删除 k 个数字之后的最小正整数。N <= 240, k <= N

class Solution {
public:
    /**
     * @param A: A positive integer which has N digits, A is a string
     * @param k: Remove k digits
     * @return: A string
     * 当某一位比后一位大时删除
     * 最后的结果如果前面是0要去掉
     */
    string DeleteDigits(string &A, int k) {
        // write your code 
        string res;
        if(A.empty())
			return res;
		res = A;
		while(k)
		{
			int i = 0;
			while(i<res.length()-1&&res[i]<=res[i+1])
				i++;
			res = res.substr(0,i)+res.substr(i+1);
			k--;
		}
		
		int i = 0;
		while(res[i]=='0')
		    i++;
		 res = res.substr(i);
		return res;  
    }
};

2. 给出一个表达式S,该表达式只包括数字、字母及方括号这三种元素。该表达式具有如下规则:数字只会出现在方括号前,它表示方括号内容的重复次数,方括号中的内容可以是普通的字符串, 也可以另一个表达式。请写一段程序,按照上述规则将输入的表达式展开成目标字符串。

class Solution {
public:
    /**
     * @param s: an expression includes numbers, letters and brackets
     * @return: a string
     * 用栈,遍历字符串入栈,当遇到']'时出栈,保存的另一个字符串dup中,出栈到'[‘时说明需要重复的都找到了
     * 然后再出栈数字,数字都出来后,将dup重复相应的次数,再入栈
     * 都遍历完之后,逐个出栈
     */
    string expressionExpand(string &s) {

        // write your code here
        string res;
        if(s.empty())
            return res;
        stack<char> sk;
        int i = 0;
        while(i<s.size())
        {
            if(s[i]==']')
            {
                string dup;
                while(sk.top()!='[')
                {
                    dup = sk.top()+dup;
                    sk.pop();
                }
                sk.pop();
                string num;
                while(!sk.empty()&&isdigit(sk.top()))
                {
                    num = sk.top()+num;
                    sk.pop();
                }
                int cnt = stoi(num);
                string str;
                while(cnt>0)
                {
                    str+=dup;
                    cnt--;
                }
                for(auto c:str)
                    sk.push(c);
            }else{
                sk.push(s[i]);
            }
            i++;
        }
        
        while(!sk.empty())
        {
            res = sk.top()+res;
            sk.pop();
        }
        return res;
    }
};

3.输入一个含有N个数字的数组,问需要几次数组里面的数字就被删完了,删的规则是这样的,每次从一个回文串里删,如果没有回文串,只能一个一个的删,返回需要的最少次数,比如输入[1,2],返回2,因为没有回文,只能一个一个的删;输入[1,4,3,1,5],返回3,因为第一次删掉3(或4)后,剩下的数组是[1,4(或3),1,5],第二次可以将回文内的数字都删掉,最后把5删掉,一共3次

4.给定一个仅包含0或1的字符串,现在可以对齐进行一种操作:01相邻时可以消除掉这两个字符,这样操作可以一直进行下去直到找不到相邻的0和1为止问这个字符串经历了操作后的最短长度
4
1100
输出 0

#include<iostream>
#include<string>
using namespace std;
class Solution {
public:
	int minlen(string &s)
	{
		int i = 0;
		while (s.size()&&i < s.size() - 1)
		{
			if ((s[i] == '0'&&s[i + 1] == '1') || s[i] == '1'&&s[i + 1] == '0')
			{
				s.erase(i, 2);
				i = 0;
			}
			else
				i++;
		}
		return s.size();
	}
};
int main()
{
	Solution s;
	string str;
	while (cin >> str)
	{
		int len = s.minlen(str);
		cout << len << endl;
	}
	return 0;
}


5.小Q手上有n种不同面值的硬币,每种硬币都有无限多个希望带尽量少的硬币,并且能组合出1到m之间(包含1和m)的所有面值
m 20 n 4
1 2 3 10
输出 5 

class Solution {
public:
    /**
    *背包问题 填满amount
    *dp[i]:表示填满i所需的数量
    */
    int coinChange(vector<int>& coins, int amount) {
        vector<int> dp(amount+1,amount+1);
        dp[0] = 0;
        for(auto coin:coins)
        {
            for(int i = coin;i<=amount;i++)
            {
                dp[i] = min(dp[i],dp[i-coin]+1);
            }
        }
        return dp[amount]>amount?-1:dp[amount];
    }
};


6.打怪兽,依次遇见N只怪兽,每只都有武力值和所需金币数,给金币会护送 ,如果没有贿赂且大于护送的武力值之和会攻击 
问所需最少金币数(只通过了70%,找不到原因)
3 n只
8 5 10武力值
1 1 2金币数
输出

#include<iostream>
#include<vector>
using namespace std;
int fun(int n,vector<int> d,vector<int> p)
{
    if(n<=0)
        return 0;
    if(n==1)
        return p[0];
    int d_min = d[0],d_max = d[0];
    int p_min = p[0],p_max = p[0];
    for(int i = 1;i<n;i++)
    {
        if(d_min>d[i])
        {
            d_max += d[i];
            p_max += p[i];
        }else if(d_max>d[i])
        {
            d_min = d_max;
            p_min = p_max ;
        }else{
            d_min +=d[i];
            d_max  = d_min;
            p_min += p[i];
            p_max = p_min;
        }
    }
    return p_min;
}
int main()
{
    int n;
    while(cin>>n)
    {
        vector<int> d(n,0);
        vector<int> p(n,0);
        for(int i = 0;i<n;i++)
        {
            int a;
            cin>>a;
            d[i] = a;
        }
        for(int i = 0;i<n;i++)
        {
            int b;
            cin>>b;
            p[i] = b;
        } 
        int res = fun(n,d,p);
        cout<<res<<endl;
    }
    
    return 0;
}

7.请设计一个类,该类在同一个进程中只能由一个实例,且该实例允许外部访问。

只能生成一个实例的类是实现了单例模式的类型。

解题思路:

1.必须把构造函数设为私有函数,防止他人创建实例。

2.在类中创建静态私有的实例,在需要时创建该实例,直到程序结束才销毁。

3.提供一个静态的公有的函数用于创建/获取静态私有对象。

class Singleton{
public:
	static Singleton* getInstance();

private:
	Singleton();
	//把拷贝构造函数和拷贝复制运算符也设为私有,防止被复制
	Singleton(const Singleton&);
	Singleton& operator=(const Singleton&);

	static Singleton* instance;
};

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值