lintcode

463. 整数排序

  • STL通用算法:
class Solution {
public:
    /**
     * @param A an integer array
     * @return void
     */
    void sortIntegers(vector<int>& A) {
        // Write your code here
        sort(A.begin(), A.end());
    }
};

要使用此函数只需用#include <algorithm> sort即可使用。

sort(begin,end),对给定区间的元素进行排序。

  • 冒泡:
class Solution {
public:
    /**
     * @param A: an integer array
     * @return: nothing
     */
    void sortIntegers(vector<int> &A) {
        // write your code here
        int i, j, temp;
        int length = A.size();
        for(i = length - 1; i > 0; i--){
            for(j = 0; j < i; j++){
                if(A[j] > A[j+1]){
                    temp = A[j+1];
                    A[j+1] = A[j];
                    A[j] = temp;
                }
            }
        }
    }
};

使用到A.size()函数,即求A的长度。

1. A + B 问题

不使用+号等数学运算符,这里用位运算。

| 或   & 和   ^异或(不同为1)

 当无进位时,a|b即为答案,有进位时,答案为忽略进位相加值+进位得到的值

class Solution {
public:
    int aplusb(int a, int b) {
        int c = 0, d = 0;
        while((a & b) != 0){
            c = (a&b) << 1; // 应该进位的值
            d = a ^ b; //忽略进位相加
            a = c;
            b = d;
        }
        return a | b;
    }
};

2. 尾部的零

设计一个算法,计算出n阶乘中尾部零的个数。

假如你把1 × 2 ×3× 4 ×……×N中每一个因数分解质因数,结果就像: 
1 × 2 × 3 × (2 × 2) × 5 × (2 × 3) × 7 × (2 × 2 ×2) ×…… 
10可以分解为2 × 5——因此只有质数2和5相乘能产生0,别的任何两个质数相乘都不能产生0,而且2,5相乘只产生一个0。 
所以,分解后的整个因数式中有多少对(2, 5),结果中就有多少个0,而分解的结果中,2的个数显然是多于5的,因此,有多少个5,就有多少个(2, 5)对。 

所以,讨论1000的阶乘结尾有几个0的问题,就被转换成了1到1000所有这些数的质因数分解式有多少个5的问题。

 

class Solution {
public:
    long long trailingZeros(long long n) {
        long long count = 0;
        while(n != 0){
            count = count + n/5;
            n = n / 5;
        }
        return count;
    }
};

6. 合并排序数组 II

合并两个排序的整数数组A和B变成一个新的数组。

这里注意定义完动态数组C,不能直接通过数组下标访问,会发生越界错误。正确方法应该是使用C.push_back(),这里使用了归并排序。

class Solution {
public:
    vector<int> mergeSortedArray(vector<int> &A, vector<int> &B) {
        // write your code here
        int i = 0, j = 0, k;
        vector<int> C;
        int lenA = A.size();
        int lenB = B.size();
        for(k = 0; k < (lenA + lenB); k++){
            if((i<lenA) && (j<lenB)){
                if(A[i] <= B[j]){
                    C.push_back(A[i]);
                    i++;
                }
                else{
                    C.push_back(B[j]);
                    j++;
                }
            }
            else if (i < lenA){
                C.push_back(A[i]);
                i++;
            }
            else{
                C.push_back(B[j]);
                j++;
            }
        }
        return C;
    }
};

8. 旋转字符串

offset=0 => "abcdefg"
offset=1 => "gabcdef"
offset=2 => "fgabcde"

这里注意offset远大于str的情况,先除余处理,否则会超时。这里用到了str.substr(),

例子:string a=str.substr(0,4); //获得字符串s中 从第0位开始的长度为4的字符串

class Solution {
public:
    void rotateString(string &str, int offset) {
        // write your code here
        if(str.size() == 0)
        return;
        offset = offset % str.size();
        str = str.substr(str.size() - offset, offset) + str.substr(0, str.size() - offset);
    }
};

另一种方法:

class Solution {
public:
    void rotateString(string &str, int offset) {
        // write your code here
        int i, j, k = 0;
        string a(str);
        if(str.size() == 0){
            return;
        }
        offset %= str.size();
        for(i = str.size()-offset; i < str.size(); i++){
            a[k++] = str[i];
        }
        
        for(j = 0; j < str.size()-offset; j++){
            a[k++] = str[j];
        }
        str = a;
        return;
    }
};

9. Fizz Buzz 问题

如果这个数被3整除,打印fizz.
如果这个数被5整除,打印buzz.

如果这个数能同时被3和5整除,打印fizz buzz.

只要注意将int转类型为string 用to_string

class Solution {
public:
    vector<string> fizzBuzz(int n) {
        // write your code here
        vector<string> a;
        int i;
        for(i = 1; i <= n; i++){
            if(i%3==0 && i%5 ==0){
                a.push_back("fizz buzz");
            }
            else if(i % 3 == 0){
                a.push_back("fizz");
            }
            else if(i % 5 == 0){
                a.push_back("buzz");
            }
            else{
                a.push_back(to_string(i)); // 将int转类型为string 用to_string
            }
        }
        return a;
    }
};

13. Implement strStr()

如果 source = "source" 和 target = "target",返回 -1。

如果 source = "abcdabcdefg" 和 target = "bcd",返回 1。

注意这里传入为地址参数。空指针为nullptr;strlen()先简单理解为串长度。

class Solution {
public:
    int strStr(const char *source, const char *target) {
        // write your code here
        if(source==nullptr || target==nullptr){
            return -1;
        }
        int lens = strlen(source);
        int lent = strlen(target);
        for(int i=0; i <= lens - lent; i++){
            int j = 0;
            for(j = 0; j < lent; j++){
                if(source[i+j] != target[j]) break;
            }
            if(j == lent) return i;
        }
        return -1;
    }
};

156. 合并区间

[                     [
  (1, 3),               (1, 6),
  (2, 6),      =>       (8, 10),
  (8, 10),              (15, 18)
  (15, 18)            ]

]

这里接触到的新知识:1、类内定义函数需要static。2、sort函数的第三个参数为自己定义的函:cmp。3、动态数组最后一个元素用result.back()调用

/**
 * Definition of Interval:
 * classs Interval {
 *     int start, end;
 *     Interval(int start, int end) {
 *         this->start = start;
 *         this->end = end;
 *     }
 * }
 */

class Solution {
public:
    static bool cmp(const Interval &A, const Interval &B){
    return (A.start < B.start);
}
    vector<Interval> merge(vector<Interval> &intervals) {
        // write your code here
        sort(intervals.begin(), intervals.end(), cmp);
        int len = intervals.size();
        if(len <= 1) return intervals;
        vector<Interval> result;
        int i = 0;
        result.push_back(intervals[0]);
        for(i = 1; i < len; i++){
            if(result.back().end >= intervals[i].start){
                result.back().end = max(result.back().end, intervals[i].end);
            }
            else{
                result.push_back(intervals[i]);
            }
        }
        return result;
    }
};

173. 链表插入排序

Given 1->3->2->0->null, return 0->1->2->3->null

第一次接触链表,需要注意的是1、定义节点是ListNode *p = new ListNode(0); 2、比较的时候利用temp->next->val,否则会丢失上一个节点,比较麻烦,这也是为什么经常使用头结点的原因

/**
 * Definition of singly-linked-list:
 * class ListNode {
 * public:
 *     int val;
 *     ListNode *next;
 *     ListNode(int val) {
 *        this->val = val;
 *        this->next = NULL;
 *     }
 * }
 */
class Solution {
public:
    ListNode * insertionSortList(ListNode * head) {
        // write your code here
        if(head == NULL) return head;
        ListNode *result = new ListNode(0);
        while(head != NULL){
            ListNode *temp = result;
            ListNode *next = head->next;
            while(temp->next!=NULL && temp->next->val<head->val){
                temp = temp->next;
            }
            head->next = temp->next;
            temp->next = head;
            head = next;
        }
        return result->next;
    }
};

464. 整数排序 II

快速排序:

class Solution {
public:
    void sortIntegers2(vector<int> &A) {
        // write your code here
        QuickSort(A, 0, A.size() - 1);
    }
private:
    void QuickSort(vector<int> &A, int l, int r){
        if(l >= r){
            return;
        }
        int i = l, j = r;
        int pivot = A[(l+r)/2];
        while(i <= j){
            while(A[j] > pivot && i<=j){
                j--;
            }
            while(A[i] < pivot && i<=j){
                i++;
            }
            if(i <= j){
                int temp = A[j];
                A[j] = A[i];
                A[i] = temp;
                i++;
                j--;
            }
        }
        QuickSort(A, i, r);
        QuickSort(A, l, j);
    }
};

547. 两数组的交

nums1 = [1, 2, 2, 1], nums2 = [2, 2], 返回 [2].

这里有几个新的知识点:1、迭代器vector<int>::iterator it; 2、unique函数。last = unique(result.begin(), result.end()); unique的作用是从输入序列中“删除”所有相邻的重复元素,作用结果保留在result数组中。其实它并不真正把重复的元素删除,是把重复的元素移到后面去了,然后依然保存到了原数组中,然后 返回去重后最后一个元素的地址,因为unique去除的是相邻的重复元素,所以一般用之前都会要排一下序。3、erase():第一个参数为起始地址,第二个参数为终止地址,删除指定位置的元素。

class Solution {
public:
    vector<int> intersection(vector<int> nums1, vector<int> nums2) {
        // write your code here
        sort(nums1.begin(), nums1.end());
        sort(nums2.begin(), nums2.end());
        vector<int> result;
        vector<int>::iterator it1 = nums1.begin(), it2 = nums2.begin();
        while(it1 != nums1.end() && it2 != nums2.end()){
            if(*it1 > *it2){
                it2++;
            }
            else if(*it1 < *it2){
                it1++;
            }
            else{
                result.push_back(*it1);
                it1++;
                it2++;
            }
        }
        auto last = unique(result.begin(), result.end());
        result.erase(last, result.end());
        return result;
    }
};

846. 多关键字排序

给出 [[2,50],[1,50],[3,100]],

返回 [[3,100],[1,50],[2,50]]

冒泡排序的思想,这里注意交换的时候是交换数组,第一次做的时候直接交换了array[j][1]和array[j+1][1]。。。无语

class Solution {
public:
    vector<vector<int>> multiSort(vector<vector<int>> &array) {
        // Write your code here
        vector<int> tmp;
        for(int i = array.size() - 1; i > 0; i--){
            for(int j = 0; j < i; j++){
                if(array[j][1] < array[j+1][1]){
                    tmp = array[j+1];
                    array[j+1] = array[j];
                    array[j] = tmp;
                }
                else if(array[j][1] == array[j+1][1]){
                    if(array[j][0] > array[j+1][0]){
                        tmp = array[j+1];
                        array[j+1] = array[j];
                        array[j] = tmp;
                    }
                }
            }
        }
        return array;
    }
};

49. 字符大小写排序

给出"abAcD",一个可能的答案为"acbAD"

str.substr()的使用

#include<iostream>
#include<string>
using namespace std;
class Solution {
public:
     bool isLower(char c){
         return (c >= 'a' && c <= 'z');
     }
    void sortLetters(string &chars) {
        // write your code here
        if(chars.size() <= 1) return;
        sort(chars.begin(), chars.end());
        int i = 0;
        while(isLower(chars[i]) == false){
            i++;
        }
        // 定义串方法:
        // string tmp(chars); 这样就可以使用串tmp了
        chars = chars.substr(i, chars.size() - i) + chars.substr(0, i);
    }
};

57. 三数之和

样例
如S = {-1 0 1 2 -1 -4}, 你需要返回的三元组集合的是:
(-1, 0, 1)

(-1, -1, 2)

本题难点在于得到最终结果时,可能会出现重复答案,在初步得到答案需要删除答案中重复部分,即利用前面所学unique()和result.erase();这里有惊喜,发现定义变量使用auto是万能的?

class Solution {
public:
    vector<vector<int>> threeSum(vector<int> &numbers) {
        // write your code here
        sort(numbers.begin(), numbers.end());
        vector<vector<int>> result;
        int i, j ,k;
        for(i = 0; i < numbers.size(); i++){
            for(j = i + 1; j < numbers.size(); j++){
                for(k = j + 1; k < numbers.size(); k++){
                    if(numbers[i] + numbers[j] + numbers[k] == 0){
                        vector<int> chars;
                        chars.push_back(numbers[i]);
                        chars.push_back(numbers[j]);
                        chars.push_back(numbers[k]);
                        result.push_back(chars);
                        sort(result.begin(), result.end());
                        auto last = unique(result.begin(), result.end());
                        result.erase(last, result.end());
                    }
                }
            }
        }
        return result;
    }
};

14.二分查找

这里使用了递归;注意存在多个目标值,取最小的小标。

class Solution {
public:
    int Search(vector<int> &nums, int target, int left, int right){
        if(left > right) return -1;
        if(left == right && target == nums[left]){
            return left;
        }
        int mid;
        mid = (left+right) / 2;
        if(target == nums[mid]){
            Search(nums, target, left, mid); //这里进入二次判断是否目标值的下标是最小的
        }
        else if(target < nums[mid]){
            Search(nums, target, left, i-1);
        }
        else{
            Search(nums, target, i+1, right);
        }
    }
    int binarySearch(vector<int> &nums, int target) {
        // write your code here
        Search(nums, target, 0, nums.size()-1);
    }
};

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值