NewCoder Algorithm Part1(有序返回最小的k个数、回文串、前序中序构建树、中序后序构建树、二进制中1的个数、数组的整数次方、把数组排成最小的数、连续子数组的最大和l )

对于一个无序数组,数组中元素为互不相同的整数,请返回其中最小的k个数,顺序与原数组中元素顺序一致。

给定一个整数数组A及它的大小n,同时给定k,请返回其中最小的k个数
class Number{
public:
    int index;
    int  value;
    Number(int index, int value){
        this->value = value;
        this->index = index;
    }
};
 bool comp1(Number n1, Number n2){
    return  n1.value < n2.value;
}
bool comp2(Number n1, Number n2){
    return  n1.index < n2.index;
}
class KthNumbers {
public:
	vector<int> findKthNumbers(vector<int> A, int n, int k) {
	vector<Number> arr;
        vector<int> res;
        if (input.size()< k) {return res;}
        for (int i = 0; i < input.size(); i++) {
            arr.push_back(Number(i,input[i]));
        }
        sort(arr.begin(), arr.end(),comp1);
        sort(arr.begin(), arr.begin()+k, comp2);
        for (int i = 0; i < k; i++) {
            res.push_back(arr[i].value);
        }
        return res;
	}
};

关于本题的说明:本题的要求是希望这个获取的最小的k个数具有稳定性,那么,为了达到这种稳定性,我们就采用了记录数据原始的下标的方式,这样的优势在于思路比较清晰,代码比较简洁。

对于一个字符串,我们想通过添加字符的方式使得新的字符串整体变成回文串,但是只能在原串的结尾添加字符,
请返回在结尾添加的最短字符串。

给定原字符串A及它的长度n,请返回添加的字符串。保证原串不是回文串。

测试样例:

"ab",2
返回:"a"

 way1:简单粗暴的方法1


class Palindrome {
public:
    string addToPalindrome(string A, int n)
    {
        int index=0;
        string str = A,res="";
        while(index<n){
            res= A[index] + res;
            str = A + res;
            if(isPalindrome(str)){
                break;}
            index++;
        }
        return res;
    }
    bool isPalindrome(string A)
    {
        string B =A;
        reverse(A.begin(),A.end());
        if(A==B)return 1;
        else return 0;
    }
};

    way2:代码简单,但是不容易理解:if(A.substr(i,n-i)==s.substr(0,n-i))看A字符串尾部和S字符串头部的公共字符串长度这个部分可以作为回文串的已经有的部分,其余部分需要添加。

string addToPalindrome(string A, int n) {
        string s = A;
        reverse(s.begin(),s.end()); // 取得翻转串
        for(int i=0;i<n;i++) // Naive查找
             if(A.substr(i,n-i)==s.substr(0,n-i))
                return s.substr(n-i,i);//返回公共集后面剩余字符串
        return string("");
    }
前序中序构建树
class Solution {
public:
    /**
     *@param preorder : A list of integers that preorder traversal of a tree
     *@param inorder : A list of integers that inorder traversal of a tree
     *@return : Root of a tree
     */
    TreeNode * buildTree(vector<int> &preorder, vector<int> &inorder) {
        // write your code here
        return proccess(preorder,inorder);
    }
    TreeNode* proccess(vector<int> &preorder, vector<int> &inorder){
        if (preorder.size() ==0) {
            return NULL;//point1 递归结束条件
        }
        vector<int> preLeft ,preRight, inorderLeft,inorderRight;
        TreeNode *root = new TreeNode(preorder[0]);
        for (int i = 0; i <inorder.size(); i++) {
            if(preorder[0] != inorder[i]){
                inorderLeft.push_back(inorder[i]);
            }
            else{break;};
        }
        for (int i = inorderLeft.size() +1; i < inorder.size(); i++) {
            inorderRight.push_back(inorder[i]);
        }
        for (int i = 1; i < inorderLeft.size() +1; i++) {
            preLeft.push_back(preorder[i]); 
        }
        for (int i = inorderLeft.size()+1; i < preorder.size(); i++) {
            preRight.push_back(preorder[i]);
        }
        root->left = proccess(preLeft, inorderLeft);
        root->right = proccess(preRight,inorderRight);
        return root;
    }
};
中序后序构建二叉树

 

class Solution {
public:
    /**
     * @param inorder: A list of integers that inorder traversal of a tree
     * @param postorder: A list of integers that postorder traversal of a tree
     * @return: Root of a tree
     */
    TreeNode * buildTree(vector<int> &inorder, vector<int> &postorder) {
        // write your code here
        return proccess(inorder,postorder);
    }
    TreeNode* proccess(vector<int> &inorder, vector<int> &postorder){
        if (postorder.size() ==0) {
            return NULL;//point1 递归结束条件
        }
        vector<int> postLeft ,postRight, inorderLeft,inorderRight;
        TreeNode *root = new TreeNode(postorder[postorder.size() -1]);
        for (int i = 0; i <inorder.size(); i++) {
            if(postorder[postorder.size()-1] != inorder[i]){
                inorderLeft.push_back(inorder[i]);
            }
            else{break;};
        }
        for (int i = inorderLeft.size() +1; i < inorder.size(); i++) {
            inorderRight.push_back(inorder[i]);
        }
        for (int i = 0; i < inorderLeft.size(); i++) {
            postLeft.push_back(postorder[i]); 
        }
        for (int i = inorderLeft.size(); i < postorder.size() -1; i++) {
            postRight.push_back(postorder[i]);
        }
        root->left = proccess(inorderLeft, postLeft);
        root->right = proccess(inorderRight,postRight);//point2
        return root;
    }
};

说明由于数组中的元素始终是不变的,可以考虑使用数组下标来代替实际元素的位置。

二进制中1的个数
class Solution {
public:
    /*
     * @param num: An integer
     * @return: An integer
     */
    int countOnes(int num) {
        // write your code here
        int count = 0;
        int flag = 1;
        while(flag){
            if(num &flag) count++;
            flag = flag<<1;//point1注意对负数的处理
        }
        return count;
    }
};
数的整数次方
class Solution {
public:
    double Power(double base, int exponent)
    {
       if(exponent>=0)
           return  P(base,  exponent);
       else
           return 1.0/( P(base,  -exponent));
    }
  double   P(double base, int exponent){
         if(exponent==0)
            return 1;
         if(exponent%2==0)
             return  P(base*base,exponent/2);
        return base* P(base*base,exponent/2); 
     }
}
//5^10  = P(5*5,5) = P(25*25,2) = p(625*525,1);
输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个。例如输入
数组{3,32,321},则打印出这三个数字能排成的最小数字为321323。

    本题的思想在于,取出两个数字,组合成两个字符,进行比较,并取得小的排列,以这样的方式排序,我们就
可以获取最小的序列也就是我们所要求的数据。
class Solution {
public:
    string PrintMinNumber(vector<int> numbers) {    
        int len = numbers.size();
         if(len==0) return "";string s ="";
       sort(numbers.begin(), numbers.end(),compare);
        for(int i =0;i<len;i++)
            s+=to_string(numbers[i]);
        return s;
    }
  static bool compare(int start,int end){
       string s1 =to_string(start);//point1
       string s2 =to_string(end);
        return (s1 + s2).compare(s2+s1);
   }   
};
HZ偶尔会拿些专业问题来忽悠那些非计算机专业的同学。今天测试组开完会后,他又发话了:在古老的一维模式识别
中,常常需要计算连续子向量的最大和,当向量全为正数的时候,问题很好解决。但是,如果向量中包含负数,是否应
该包含某个负数,并期望旁边的正数会弥补它呢?例如:{6,-3,-2,7,-15,1,2,2},连续子向量的最大和为8(从第0
个开始,到第3个为止)。给一个数组,返回它的最大连续子序列的和,你会不会被他忽悠住?(子向量的长度至少是
1)。

class Solution {
public:
    /**
     * @param nums: A list of integers
     * @return: A integer indicate the sum of max subarray
     */
    int maxSubArray(vector<int> &nums) {
    int sum =nums[0], max =nums[0],len =nums.size();
        for(int i = 1; i < len; i++){
             if(sum >= 0)
                sum = sum + nums[i];
            else 
                sum =nums[i];
            if(sum> max) max = sum;
        }
         return max;
    }
};

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值