[lintcode] 简单

 

2. 尾部的零

描述

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

您在真实的面试中是否遇到过这个题?  是

样例

11! = 39916800,因此应该返回 2

挑战

O(logN)的时间复杂度

class Solution {
public:
    /*
     * @param n: A long integer
     * @return: An integer, denote the number of trailing zeros in n!
     */
    long long trailingZeros(long long n) {
        // write your code here, try to do it without arithmetic operators.
        long count = 0;
        long temp = n/5;
        while(temp != 0){
            count += temp;
            temp /= 5;
        }
        return count;
    }
};

 

 

6. 合并排序数组 II

描述

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

您在真实的面试中是否遇到过这个题?  是

样例

给出A=[1,2,3,4],B=[2,4,5,6],返回 [1,2,2,3,4,4,5,6]

挑战

你能否优化你的算法,如果其中一个数组很大而另一个数组很小?

class Solution {
public:
    /**
     * @param A: sorted integer array A
     * @param B: sorted integer array B
     * @return: A new sorted integer array
     */
    vector<int> mergeSortedArray(vector<int> &A, vector<int> &B) {
        // write your code here
        int m = A.size(); int n = B.size();
        vector<int> result;
        int i = 0, j = 0;
        while (i < A.size() && j < B.size()) {
            if (A[i] < B[j]) {
                result.push_back(A[i++]);
            } else {
                result.push_back(B[j++]);
            }
        }
        while (i < A.size()) {
            result.push_back(A[i++]);
        }
        while (j < B.size()) {
            result.push_back(B[j++]);
        }
        return result;}
};

 

 

8. 旋转字符串

描述

给定一个字符串和一个偏移量,根据偏移量旋转字符串(从左向右旋转)

您在真实的面试中是否遇到过这个题?  是

样例

对于字符串 "abcdefg".

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

挑战

在数组上原地旋转,使用O(1)的额外空间

class Solution {
public:
    /**
     * @param str: a string
     * @param offset: an integer
     * @return: nothing
     */
    void reverseString(string& str, int start, int end) {
        while(start < end) {
            char tmp = str[start];
            str[start] = str[end];
            str[end] = tmp;
            ++start;
            --end;
        }
    } 
     
    void rotateString(string &str,int offset){
        //wirte your code here
        if(offset < 0 || str.empty())
            return;
        int len = (int)str.length();
        offset =  len - offset % len;
        
        reverseString(str, 0, offset-1);
        reverseString(str, offset, len-1);
        reverseString(str, 0 , len-1);
    }
};

 

9. Fizz Buzz 问题

描述

给你一个整数n. 从 1 到 n 按照下面的规则打印每个数:

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

您在真实的面试中是否遇到过这个题?  是

样例

比如 n = 15, 返回一个字符串数组:

[
  "1", "2", "fizz",
  "4", "buzz", "fizz",
  "7", "8", "fizz",
  "buzz", "11", "fizz",
  "13", "14", "fizz buzz"
]

挑战

Can you do it with only one if statement?

class Solution {
public:
    /**
     * @param n: An integer
     * @return: A list of strings.
     */
    vector<string> fizzBuzz(int n) {
        // write your code here
        vector<string> result;
        for(int i = 1; i<=n ; i++)
        {
            if(i%15 == 0) 
                result.push_back("fizz buzz");
            else if(i%5 == 0) 
                result.push_back("buzz");
            else if(i%3 == 0) 
                result.push_back("fizz");
            else result.push_back(to_string(i));
        }
        return result;
    }
};

 

 

13. 字符串查找

描述

对于一个给定的 source 字符串和一个 target 字符串,你应该在 source 字符串中找出 target 字符串出现的第一个位置(从0开始)。如果不存在,则返回 -1

您在真实的面试中是否遇到过这个题?  是

说明

在面试中我是否需要实现KMP算法?

  • 不需要,当这种问题出现在面试中时,面试官很可能只是想要测试一下你的基础应用能力。当然你需要先跟面试官确认清楚要怎么实现这个题。

样例

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

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

挑战

O(n2)的算法是可以接受的。如果你能用O(n)的算法做出来那更加好。(提示:KMP)

class Solution {
public:
    /**
     * Returns a index to the first occurrence of target in source,
     * or -1  if target is not part of source.
     * @param source string to be scanned.
     * @param target string containing the sequence of characters to match.
     */

   int strStr(const char *source, const char *target) {
       if(source == '\0')   return -1;
       if(target == '\0')   return -1;

        // write your code here
        int m = strlen(source);
        int n = strlen(target);
        
        if(m == 0 && n == 0)
            return 0;
        int j;
        int i;
        for(i=0; i<m; i++){
            for(j=0; j<n && i+j<m; j++){
                if(source[i+j] != target[j])
                    break;
            }
            if(j == n)
                return i;
        }
        return -1;
    }
};

 

14. 二分查找

描述

给定一个排序的整数数组(升序)和一个要查找的整数target,用O(logn)的时间查找到target第一次出现的下标(从0开始),如果target不存在于数组中,返回-1

您在真实的面试中是否遇到过这个题?  是

样例

在数组 [1, 2, 3, 3, 4, 5, 10] 中二分查找3,返回2

class Solution {
public:
    /**
     * @param nums: The integer array.
     * @param target: Target to find.
     * @return: The first position of target. Position starts from 0.
     */
    int binarySearch(vector<int> &nums, int target) {
        // write your code here
    if (nums.size() == 0) return -1;
    int start = 0;
    int end = nums.size() - 1;
    // 要点1: 再找最后一个对象时,必须使用start + 1 < end,
    //      当使用start < end时,在[1,1],1的场景下会出现死循环。
    while (start + 1 < end) {
        int mid = start + (end - start) / 2;
        if (nums[mid] == target) {
            // 这里不能return,需要把end设置为mid,继续往前找。
            end = mid;} 
        else if (nums[mid] > target)
            end = mid;
        else
            start = mid;
    }
    // 要点2: 要把start先比较
    if (nums[start] == target) 
        return start;
    if (nums[end] == target)
        return end;
    return -1;
    }
};

 

 

22. 平面列表

描述

给定一个列表,该列表中的每个要素要么是个列表,要么是整数。将其变成一个只包含整数的简单列表。

如果给定的列表中的要素本身也是一个列表,那么它也可以包含列表。

您在真实的面试中是否遇到过这个题?  是

样例

给定 [1,2,[1,2]],返回 [1,2,1,2]

给定 [4,[3,[2,[1]]]],返回 [4,3,2,1]

class Solution {
public:
    // @param nestedList a list of NestedInteger
    // @return a list of integer
    vector<int> flatten(vector<NestedInteger> &nestedList) {
        // Write your code here
        vector<int> result;
        addAll(result,nestedList);
        return result;
    }
    
    void addAll(vector<int> &result,const vector<NestedInteger> &from){
        for(int i=0;i<from.size();++i){
            if(from[i].isInteger()){
                result.push_back(from[i].getInteger());
            }
            else{
                addAll(result,from[i].getList());
            }
        }
    }
};

 

28. 搜索二维矩阵

描述

写出一个高效的算法来搜索 m × n矩阵中的值。

这个矩阵具有以下特性:

  • 每行中的整数从左到右是排序的。
  • 每行的第一个数大于上一行的最后一个整数。

您在真实的面试中是否遇到过这个题?  是

样例

考虑下列矩阵:

[
  [1, 3, 5, 7],
  [10, 11, 16, 20],
  [23, 30, 34, 50]
]

给出 target = 3,返回 true

class Solution {
public:
    /**
     * @param matrix: matrix, a list of lists of integers
     * @param target: An integer
     * @return: a boolean, indicate whether matrix contains target
     */
    bool searchMatrix(vector<vector<int>> &matrix, int target) {
        // write your code here
        int sizeRow=matrix.size();
            if(sizeRow==0) 
                    return false;
        int sizeCol=matrix[0].size();
            if(sizeCol==0) 
                    return false;
                    
        int begin =0;
        int end=    sizeRow*sizeCol-1;
        
        while(begin<=end)
        {
            int mid=(begin+end)/2;
            int m=mid/sizeCol;
            int n=mid%sizeCol;
            
            if(matrix[m][n]==target)
                return true;
            else if(matrix[m][n]>target)
            {
                end=mid-1;
            }
            else
            {
                begin=mid+1;
            }
        }
        return false;
        

        
    }
};

 

30. 插入区间

描述

Given a non-overlapping interval list which is sorted by start point.

Insert a new interval into it, make sure the list is still in order and non-overlapping (merge intervals if necessary).

您在真实的面试中是否遇到过这个题?  是

样例

Insert (2, 5) into [(1,2), (5,9)], we get [(1,9)].

Insert (3, 4) into [(1,2), (5,9)], we get [(1,2), (3,4), (5,9)].

/**
 * Definition of Interval:
 * classs Interval {
 *     int start, end;
 *     Interval(int start, int end) {
 *         this->start = start;
 *         this->end = end;
 *     }
 */
class Solution {
public:
    /**
     * Insert newInterval into intervals.
     * @param intervals: Sorted interval list.
     * @param newInterval: new interval.
     * @return: A new interval list.
     */
    vector<Interval> insert(vector<Interval> &intervals, Interval newInterval) {
        vector<Interval> result;

        size_t i = 0;
        for (; i != intervals.size(); ++i) {
            if (intervals[i].end < newInterval.start) result.push_back(intervals[i]);
            else break;
        }

        for (; i != intervals.size(); ++i) {
            if (newInterval.end < intervals[i].start) break;
            else {
                newInterval.start = min(newInterval.start, intervals[i].start);
                newInterval.end = max(newInterval.end, intervals[i].end);
            }
        }

        result.push_back(newInterval);

        for (; i != intervals.size(); ++i) {
            result.push_back(intervals[i]);
        }

        return result;
    }
};

 

35. 翻转链表

描述

翻转一个链表

您在真实的面试中是否遇到过这个题?  是

样例

给出一个链表1->2->3->null,这个翻转后的链表为3->2->1->null

挑战

在原地一次翻转完成

/**
 * Definition of singly-linked-list:
 *
 * class ListNode {
 * public:
 *     int val;
 *     ListNode *next;
 *     ListNode(int val) {
 *        this->val = val;
 *        this->next = NULL;
 *     }
 * }
 */

class Solution {
public:
    /**
     * @param head: n
     * @return: The new head of reversed linked list.
     */
    ListNode * reverse(ListNode * head) {
        // write your code here
        if(!head || !head->next) return head;
        ListNode* tmp = NULL;
        while(head) {
            ListNode * node = head->next;
            head->next = tmp;
            tmp = head;
            head = node;
        }
        return tmp;
    }
};

 

39. 恢复旋转排序数组

描述

给定一个旋转排序数组,在原地恢复其排序。

您在真实的面试中是否遇到过这个题?  是

说明

什么是旋转数组?

  • 比如,原始数组为[1,2,3,4], 则其旋转数组可以是[1,2,3,4], [2,3,4,1], [3,4,1,2], [4,1,2,3]

样例

[4, 5, 1, 2, 3] -> [1, 2, 3, 4, 5]

挑战

使用O(1)的额外空间和O(n)时间复杂度

class Solution {
public:
    /**
     * @param nums: An integer array
     * @return: nothing
     */
    void recoverRotatedSortedArray(vector<int> &nums) {
        // write your code here
        int p = 0;
        int m = nums.size();
        for(int i = 0; i < m-2; i++)
        {
            if(nums[i+1] < nums[i]) 
            {
                p = i;
                break;
            }
        }
        if(p!= 0)
        {recover(nums, 0, p);
        recover(nums, p+1, m-1);
        recover(nums, 0, m-1);}
    }
    void recover(vector<int> &nums, int begin, int end)
    {
        int i = 0;int j = 0; 
        for(i = begin,j = end; i<begin+(end-begin+1)/2; i++, j--)
            swap(nums[i], nums[j]);
    }
};

 

41. 最大子数组

描述

给定一个整数数组,找到一个具有最大和的子数组,返回其最大和。

子数组最少包含一个数

您在真实的面试中是否遇到过这个题?  是

样例

给出数组[−2,2,−3,4,−1,2,1,−5,3],符合要求的子数组为[4,−1,2,1],其最大和为6

挑战

要求时间复杂度为O(n)

class Solution {
public:
    /**
     * @param nums: A list of integers
     * @return: A integer indicate the sum of max subarray
     */
    int maxSubArray(vector<int> &nums) {
        // write your code here
        int size = nums.size();
        if(size == 0) return 0;
        if(size == 1) return nums[0];
        int sum = 0; int maxsum = INT_MIN; int minsum = 0;
        for(int i = 0; i<size; i++)
        {
            sum +=nums[i];
            maxsum = max(sum - minsum, maxsum);
            minsum = min(sum, minsum);
        }
        return maxsum;
    }
};

 

44. 最小子数组

描述

给定一个整数数组,找到一个具有最小和的子数组。返回其最小和。

子数组最少包含一个数字

您在真实的面试中是否遇到过这个题?  是

样例

给出数组[1, -1, -2, 1],返回 -3

class Solution {
public:
    /*
     * @param nums: a list of integers
     * @return: A integer indicate the sum of minimum subarray
     */
    int minSubArray(vector<int> &nums) {
        // write your code here
        int size = nums.size();
        if(size == 1) return nums[0];
        int sum = 0; int minsum = INT_MAX;
        for(int i = 0; i<size; i++)
            {
                sum = min(sum+nums[i], nums[i]);
                minsum = min(sum,minsum);
            }
        return minsum;
    }
};

 

 

46. Majority Element

描述

给定一个整型数组,找出主元素,它在数组中的出现次数严格大于数组元素个数的二分之一。

 

You may assume that the array is non-empty and the majority number always exist in the array.

您在真实的面试中是否遇到过这个题?  是

样例

给出数组[1,1,1,1,2,2,2],返回 1

挑战

要求时间复杂度为O(n),空间复杂度为O(1)

class Solution {
public:
    /*
     * @param nums: a list of integers
     * @return: find a  majority number
     */
    int majorityNumber(vector<int> &nums) {
        // write your code here
        sort(nums.begin(), nums.end());
        int size = nums.size();
        int half = size/2;
        int count = 1;
        for(int i = 0; i<size-1; i++)
        {
            if(nums[i] == nums[i+1]) 
            {
                count++;
                if(count > half) 
                    return nums[i];
            }
            else count = 1;
        }
    }
};

 

53. 翻转字符串

描述

给定一个字符串,逐个翻转字符串中的每个单词。

您在真实的面试中是否遇到过这个题?  是

说明

  • 单词的构成:无空格字母构成一个单词
  • 输入字符串是否包括前导或者尾随空格?可以包括,但是反转后的字符不能包括
  • 如何处理两个单词间的多个空格?在反转字符串中间空格减少到只含一个

样例

给出s = "the sky is blue",返回"blue is sky the"

class Solution {
public:
    /*
     * @param s: A string
     * @return: A string
     */
    string reverseWords(string s) {
        int size=s.size(), len=0, start=0, end=0;
        reverse(s.begin(), s.end());
        
        for(;start<size; ++start) {
            if(s[start]!=' ') {
                if(len!=0) {
                    s[len++]=' ';
                }
                int end=start;
                while(end<size&&s[end]!=' ') s[len++]=s[end++];
                reverse(s.begin()+len-(end-start), s.begin()+len);
                start=end;
            }
        }
        return s.substr(0, len);
    }
};

 

55. 比较字符串

描述

比较两个字符串A和B,确定A中是否包含B中所有的字符。字符串A和B中的字符都是 大写字母

在 A 中出现的 B 字符串里的字符不需要连续或者有序。

您在真实的面试中是否遇到过这个题?  是

样例

给出 A = "ABCD" B = "ACD",返回 true

给出 A = "ABCD" B = "AABC", 返回 false

class Solution {
public:
    /**
     * @param A: A string
     * @param B: A string
     * @return: if string A contains all of the characters in B return true else return false
     */
    bool compareStrings(string A, string B) {
        // write your code here
        if(B.size() == 0) return true;
        int count = 0;
        for(int i =0;i<B.size();i++)
        {
            for(int j = 0; j<A.size(); j++)
            {
                if(A[j] == B[i])
                {
                    A[j] = 0;
                    count ++;
                    break;
                }
            }
        }
        if(count == B.size()) return true;
        else return false;
    }
};

 

56. 两数之和

描述

给一个整数数组,找到两个数使得他们的和等于一个给定的数 target

你需要实现的函数twoSum需要返回这两个数的下标, 并且第一个下标小于第二个下标。注意这里下标的范围是 0 到 n-1

你可以假设只有一组答案。

您在真实的面试中是否遇到过这个题?  是

样例

给出 numbers = [2, 7, 11, 15], target = 9, 返回 [0, 1].

挑战

Either of the following solutions are acceptable:

  • O(n) Space, O(nlogn) Time
  • O(n) Space, O(n) Time
class Solution {
public:
    /**
     * @param numbers: An array of Integer
     * @param target: target = numbers[index1] + numbers[index2]
     * @return: [index1, index2] (index1 < index2)
     */
    vector<int> twoSum(vector<int> &nums, int target) {

        unordered_map<int,int>mapping;
        vector<int> a;
        for(int i=0;i<nums.size();i++)
            mapping[nums[i]]=i;
        for(int i=0;i<nums.size();i++)
        {
            unsigned int result=target-nums[i];
            if(mapping.find(result)!=mapping.end()&&mapping[result]>i)
            { a.push_back(i);
            a.push_back(mapping[result]);
            }
        }
        return a;
    }
};

 

60. 搜索插入位置

描述

给定一个排序数组和一个目标值,如果在数组中找到目标值则返回索引。如果没有,返回到它将会被按顺序插入的位置。

你可以假设在数组中无重复元素。

您在真实的面试中是否遇到过这个题?  是

样例

[1,3,5,6],5 → 2

[1,3,5,6],2 → 1

[1,3,5,6], 7 → 4

[1,3,5,6],0 → 0

挑战

O(log(n)) time

class Solution {
public:
    /**
     * @param A: an integer sorted array
     * @param target: an integer to be inserted
     * @return: An integer
     */
    int searchInsert(vector<int> &A, int target) {
        // write your code here
        int size = A.size(); 
        if(A.size() == 0) return 0;
        for(int i = 0; i<A.size(); i++)
        {
            if(A[i] == target) return i;
            if(A[i] > target) return i;
        }
        if(A[-1] < target) return size;
    }
};

 

64. 合并排序数组

描述

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

你可以假设A具有足够的空间(A数组的大小大于或等于m+n)去添加B中的元素。

您在真实的面试中是否遇到过这个题?  是

样例

给出 A = [1, 2, 3, empty, empty], B = [4, 5]

合并之后 A 将变成 [1,2,3,4,5]

class Solution {
public:
    /*
     * @param A: sorted integer array A which has m elements, but size of A is m+n
     * @param m: An integer
     * @param B: sorted integer array B which has n elements
     * @param n: An integer
     * @return: nothing
     */
    void mergeSortedArray(int A[], int m, int B[], int n) {
        // write your code here
        int all = m + n;
        while(m >= 0 && n >= 0)
        {
            if(A[m - 1] > B[n - 1]) A[--all] = A[--m];
            else A[--all] = B[--n];
        }
        while(n >= 0) A[--all] = B[--n];
    }
};

 

66. 二叉树的前序遍历

给出一棵二叉树,返回其节点值的前序遍历。

样例

给出一棵二叉树 {1,#,2,3},

   1
    \
     2
    /
   3 

 返回 [1,2,3].

挑战

你能使用非递归实现么?

/**
 * Definition of TreeNode:
 * class TreeNode {
 * public:
 *     int val;
 *     TreeNode *left, *right;
 *     TreeNode(int val) {
 *         this->val = val;
 *         this->left = this->right = NULL;
 *     }
 * }
 */

class Solution {
public:
    /**
     * @param root: A Tree
     * @return: Preorder in ArrayList which contains node values.
     */
    vector<int> preorderTraversal(TreeNode * root) {
        // write your code here
        vector<int> nums;
        preorder(root, nums);
        return nums;
        
    }
    void preorder(TreeNode * root, vector<int> &nums)
    {
        if(root != NULL)
        {
            nums.push_back(root -> val);
            preorder(root -> left, nums);
            preorder(root -> right, nums);
        }
    }
};

 

67. 二叉树的中序遍历

给出一棵二叉树,返回其中序遍历

样例

给出二叉树 {1,#,2,3},

   1
    \
     2
    /
   3

返回 [1,3,2].

挑战

你能使用非递归算法来实现么?

/**
 * Definition of TreeNode:
 * class TreeNode {
 * public:
 *     int val;
 *     TreeNode *left, *right;
 *     TreeNode(int val) {
 *         this->val = val;
 *         this->left = this->right = NULL;
 *     }
 * }
 */

class Solution {
public:
    /**
     * @param root: A Tree
     * @return: Inorder in ArrayList which contains node values.
     */
    vector<int> inorderTraversal(TreeNode * root) {
        // write your code here
        vector<int> nums;
        inorder(root, nums);
        return nums;
    }
    void inorder(TreeNode * root, vector<int> &nums)
    {
        if(root != NULL)
        {
            inorder(root -> left, nums);
            nums.push_back(root -> val);
            inorder(root -> right, nums);
        }
    }
};

 

68. 二叉树的后序遍历

给出一棵二叉树,返回其节点值的后序遍历。

样例

给出一棵二叉树 {1,#,2,3},

   1
    \
     2
    /
   3

返回 [3,2,1]

挑战

你能使用非递归实现么?

/**
 * Definition of TreeNode:
 * class TreeNode {
 * public:
 *     int val;
 *     TreeNode *left, *right;
 *     TreeNode(int val) {
 *         this->val = val;
 *         this->left = this->right = NULL;
 *     }
 * }
 */

class Solution {
public:
    /**
     * @param root: A Tree
     * @return: Postorder in ArrayList which contains node values.
     */
    vector<int> postorderTraversal(TreeNode * root) {
        // write your code here
        vector<int> nums;
        postorder(root, nums);
        return nums;
    }
    void postorder(TreeNode * root, vector<int> &nums)
    {
        if(root != NULL)
        {
            postorder(root -> left, nums);
            postorder(root -> right, nums);
            nums.push_back(root -> val);
        }
    }
};

 

69. 二叉树的层次遍历

给出一棵二叉树,返回其节点值的层次遍历(逐层从左往右访问)

样例

给一棵二叉树 {3,9,20,#,#,15,7} :

  3
 / \
9  20
  /  \
 15   7

返回他的分层遍历结果:

[
  [3],
  [9,20],
  [15,7]
]

挑战

挑战1:只使用一个队列去实现它

挑战2:用DFS算法来做

class Solution {
    vector<vector<int>> ans;
    void dfs(TreeNode * node,int level)
    {
        if (!node) return;
        if (ans.size()<level+1)
            ans.resize(level+1);
        
        dfs(node->left,level+1);
        vector<int>& v = ans[level];
        v.push_back(node->val);
        dfs(node->right,level+1);
    }
public:
    vector<vector<int>> levelOrder(TreeNode * root) {
        dfs(root,0);
        return ans;
    }
};

 

80. 中位数

给定一个未排序的整数数组,找到其中位数。

中位数是排序后数组的中间值,如果数组的个数是偶数个,则返回排序后数组的第N/2个数。

样例

给出数组[4, 5, 1, 2, 3], 返回 3

给出数组[7, 9, 4, 5],返回 5

挑战

时间复杂度为O(n)

class Solution {
public:
    /**
     * @param nums: A list of integers
     * @return: An integer denotes the middle number of the array
     */
    int median(vector<int> &nums) {
        // write your code here
        sort(nums.begin(), nums.end());
        int size = nums.size();
        if(size%2 == 0) return nums[size/2 -1];
        else return nums[size/2 ];
    }
};

 

82. 落单的数

给出2*n + 1 个的数字,除其中一个数字之外其他每个数字均出现两次,找到这个数字。

 

样例

给出 [1,2,2,1,3,4,3],返回 4

挑战

一次遍历,常数级的额外空间复杂度

class Solution {
public:
    /**
     * @param A: An integer array
     * @return: An integer
     */
    int singleNumber(vector<int> &A) {
        map<int,int> m;
        for(int i=0;i<A.size();i++){
            m[A[i]]++;
        }
        for(int i=0;i<A.size();i++){
            if(m[A[i]]==1){
                return A[i];
            }
        }
        return -1;
    }
};

 

85. 在二叉查找树中插入节点

给定一棵二叉查找树和一个新的树节点,将节点插入到树中。

你需要保证该树仍然是一棵二叉查找树。

样例

给出如下一棵二叉查找树,在插入节点6之后这棵二叉查找树可以是这样的:

  2             2
 / \           / \
1   4   -->   1   4
   /             / \ 
  3             3   6

挑战

能否不使用递归?

注意事项

You can assume there is no duplicate values in this tree + node.

/**
 * Definition of TreeNode:
 * class TreeNode {
 * public:
 *     int val;
 *     TreeNode *left, *right;
 *     TreeNode(int val) {
 *         this->val = val;
 *         this->left = this->right = NULL;
 *     }
 * }
 */
class Solution {
public:
    /**
     * @param root: The root of the binary search tree.
     * @param node: insert this node into the binary search tree
     * @return: The root of the new binary search tree.
     */
    TreeNode* insertNode(TreeNode* root, TreeNode* node) {
        if(root == NULL) return node;
        
        if(root -> val > node -> val)
            root -> left = insertNode(root -> left, node);
        
        else if(root -> val <  node -> val)
            root -> right = insertNode(root -> right, node);
            
        return root;
    }
};

 

93. 平衡二叉树

给定一个二叉树,确定它是高度平衡的。对于这个问题,一棵高度平衡的二叉树的定义是:一棵二叉树中每个节点的两个子树的深度相差不会超过1。 

样例

给出二叉树 A={3,9,20,#,#,15,7}, B={3,#,20,15,7}

A)  3            B)    3 
   / \                  \
  9  20                 20
    /  \                / \
   15   7              15  7

二叉树A是高度平衡的二叉树,但是B不是

输入测试数据 (每行一个参数)

class Solution {    // return the height of current root, -1 means not balanced
    int helper(TreeNode* node) {
        if (!node) return 0;
        int l = helper(node->left);
        if (l == -1) return -1;     // early stop
        int r = helper(node->right);
        if (r == -1 or abs(l - r) > 1)
            return -1;
        return 1 + max(l, r);
    }
    
public:
    bool isBalanced(TreeNode* root) {
        return helper(root) != -1;
    }
};

 

96. 链表划分

给定一个单链表和数值x,划分链表使得所有小于x的节点排在大于等于x的节点之前。

你应该保留两部分内链表节点原有的相对顺序。

 

样例

给定链表 1->4->3->2->5->2->null,并且 x=3

返回 1->2->2->4->3->5->null

/**
 * Definition of singly-linked-list:
 * class ListNode {
 * public:
 *     int val;
 *     ListNode *next;
 *     ListNode(int val) {
 *        this->val = val;
 *        this->next = NULL;
 *     }
 * }
 */

class Solution {
public:
    /**
     * @param head: The first node of linked list
     * @param x: An integer
     * @return: A ListNode
     */
    ListNode * partition(ListNode * head, int x) {
        ListNode * d1 = new ListNode(0);
        ListNode * d2 = new ListNode(0);
        ListNode * p = d1;
        ListNode * q = d2;
        ListNode *cur = head;
        while(cur != NULL)
        {
            if(cur -> val < x)
            {
                p ->next = cur;
                p = p->next;
            }
            if(cur -> val >= x)
            {
                q ->next = cur;
                q = q -> next;
            }
            cur = cur ->next;
        }
        q -> next =NULL;
        p ->next = d2->next;
        return d1->next;
    }
};

 

97. 二叉树的最大深度

给定一个二叉树,找出其最大深度。

二叉树的深度为根节点到最远叶子节点的距离。

样例

给出一棵如下的二叉树:

  1
 / \ 
2   3
   / \
  4   5

这个二叉树的最大深度为3.

输入测试数据 (每行一个参数)

class Solution {
public:
    /**
     * @param root: The root of binary tree.
     * @return: An integer
     */
    int maxDepth(TreeNode *root) {
        if (root == NULL) {
            return 0;
        }
        int left = maxDepth(root->left);
        int right = maxDepth(root->right);
        return left > right ? left + 1 : right + 1;
    }
};

 

100. 删除排序数组中的重复数字

给定一个排序数组,在原数组中删除重复出现的数字,使得每个元素只出现一次,并且返回新的数组的长度。

不要使用额外的数组空间,必须在原地没有额外空间的条件下完成。

样例

给出数组A =[1,1,2],你的函数应该返回长度2,此时A=[1,2]

class Solution {
public:
    /*
     * @param nums: An ineger array
     * @return: An integer
     */
    int removeDuplicates(vector<int> &nums) {
        // write your code here
        if(nums.size() == 0) return NULL;
        int len = 0;
        for(int i = 1; i<nums.size(); i++)
            if(nums[len] != nums[i])
                nums[++len] = nums[i];
                return len+1;
    }
};

 

101. 删除排序数组中的重复数字 II

跟进“删除重复数字”:

如果可以允许出现两次重复将如何处理?

class Solution {
public:
    /**
     * @param A: a list of integers
     * @return : return an integer
     */
    int removeDuplicates(vector<int> &nums) {
        // write your code here
        if(nums.size() == 0) return NULL;
        int len = 2;
        for(int i =2; i<nums.size(); i++)
        {
            if(nums[len-2] != nums[i]) 
                nums[len++] = nums[i];
        }
        return len;
    }
};

 

109. 数字三角形

给定一个数字三角形,找到从顶部到底部的最小路径和。每一步可以移动到下面一行的相邻数字上。

样例

比如,给出下列数字三角形:

[
     [2],
    [3,4],
   [6,5,7],
  [4,1,8,3]
]

从顶到底部的最小路径和为11 ( 2 + 3 + 5 + 1 = 11)。

注意事项

如果你只用额外空间复杂度O(n)的条件下完成可以获得加分,其中n是数字三角形的总行数。

class Solution {
public:
    /**
     * @param triangle: a list of lists of integers
     * @return: An integer, minimum path sum
     */
    int minimumTotal(vector<vector<int>>& triangle) {
		vector<int> dp(triangle.back());
		for (int i = triangle.size() - 2; i >= 0; --i) {
			for (int j = 0; j <= i; ++j) {
				dp[j] = min(dp[j], dp[j + 1]) + triangle[i][j];
			}
		}
		return dp[0];
	}
};

 

110. 最小路径和

给定一个只含非负整数的m*n网格,找到一条从左上角到右下角的可以使数字和最小的路径。

注意事项

你在同一时间只能向下或者向右移动一步

class Solution {
public:
    /**
     * @param grid: a list of lists of integers.
     * @return: An integer, minimizes the sum of all numbers along its path
     */
    int minPathSum(vector<vector<int> > &grid) {
        // write your code here
        int m=grid.size(), n=grid[0].size();
        for(int i=0;i<m;i++)
            for(int j=0;j<n;j++)
            {
                if(i||j)
                    if(i==0)
                        grid[i][j]=grid[i][j-1]+grid[i][j];
                    else if(j==0)
                        grid[i][j]=grid[i-1][j]+grid[i][j];
                    else
                        grid[i][j]=min(grid[i-1][j],grid[i][j-1])+grid[i][j];
            }
        return grid[m-1][n-1];
    }
};

 

111. 爬楼梯

假设你正在爬楼梯,需要n步你才能到达顶部。但每次你只能爬一步或者两步,你能有多少种不同的方法爬到楼顶部?

样例

比如n=3,1+1+1=1+2=2+1=3,共有3种不同的方法

返回 3

class Solution {
public:
    /**
     * @param n: An integer
     * @return: An integer
     */
    int climbStairs(int n) {
        // write your code here
        if(n == 0) return 0;
        if(n == 1) return 1;
        if(n == 2) return 2;
        
        vector<int> nums(n);
        nums[0] = 1;
        nums[1] = 2;
        for(int i = 2;i<n;i++){
            nums[i] = nums[i-1] + nums[i-2];
        }
        
        return nums[n-1];
    }
};

 

112. 删除排序链表中的重复元素

给定一个排序链表,删除所有重复的元素每个元素只留下一个。

样例

给出 1->1->2->null,返回 1->2->null

给出 1->1->2->3->3->null,返回 1->2->3->null

class Solution {
public:
    ListNode * deleteDuplicates(ListNode * head) {
		if(!head) return head;
		ListNode *p = head;
		while (p) {
			while(p->next && p->val == p->next->val)
			    p->next = p->next->next;
			p = p->next;
		}
		return head;
	}
};

 

114. 不同的路径

有一个机器人的位于一个 m × n 个网格左上角。

机器人每一时刻只能向下或者向右移动一步。机器人试图达到网格的右下角。

问有多少条不同的路径?

样例

给出 m = 3 和 n = 3, 返回 6.
给出 m = 4 和 n = 5, 返回 35.

注意事项

n和m均不超过100

class Solution {
public:
    int uniquePaths(int m, int n) {
    	vector<int> path(n, 1);
		for (int i = 1; i < m; ++i){
			for (int j = 1; j < n; ++j){
				path[j] += path[j - 1];
			}
		}
		return path[n-1];
    }
};

 

141. x的平方根

实现 int sqrt(int x) 函数,计算并返回 x 的平方根。

样例

sqrt(3) = 1

sqrt(4) = 2

sqrt(5) = 2

sqrt(10) = 3

挑战

O(log(x))

class Solution {
public:
    /**
     * @param x: An integer
     * @return: The sqrt of x
     */
    int sqrt(int x) {
        // write your code here
        if (x == 0)
    		{
    			return 0;
    		}
    		int left = 1, right = 46341;
    		int mid = 0;
    		
    		while (left < right)
    		{
    			//cout << mid << endl;
    			if (mid == (left + right) / 2)
    			{
    				break;
    			}
    			mid = (left + right) / 2;
    			if (mid*mid == x)
    			{
    				return mid;
    			} else if (mid*mid < x)
    			{
    				left = mid;
    			} else
    			{
    				right = mid;
    			}
    		}
    		return mid;
    	}
};

 

155. 二叉树的最小深度

给定一个二叉树,找出其最小深度。

二叉树的最小深度为根节点到最近叶子节点的距离。

样例

给出一棵如下的二叉树:

        1

     /     \ 

   2       3

          /    \

        4      5  

这个二叉树的最小深度为 2

class Solution {
public:
    /**
     * @param root: The root of binary tree
     * @return: An integer
     */
    int minDepth(TreeNode * root) {
        // write your code here
        if (root == NULL) {
            return 0;
        }
        
        int left = minDepth(root -> left);
        int right = minDepth(root -> right);
        
        if (left == 0) {
            return right + 1;
        } else if (right == 0) {
            return left + 1;
        }
        
        return min(left, right) + 1;
    }
};

 

156. 合并区间

给出若干闭合区间,合并所有重叠的部分。

样例

Given intervals => merged intervals:

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

挑战

O(n log n) 的时间和 O(1) 的额外空间。

输入测试数据 (每行一个参数)

class Solution {
public:
    vector<Interval> merge(vector<Interval>& intervals) {
        vector<Interval> res;
        if (intervals.empty()) return res;
        sort(intervals.begin(), intervals.end(), [](Interval& a, Interval& b){return a.start < b.start;});
        int s = intervals[0].start, e = intervals[0].end;
        for (int i = 1; i < intervals.size(); ++i) {
            if (intervals[i].start > e) {
                res.emplace_back(s, e);
                s = intervals[i].start;
            }
            e = max(e, intervals[i].end);
        }
        res.emplace_back(s, e);
        return res;
    }
};

 

165. 合并两个排序链表

将两个排序链表合并为一个新的排序链表

样例

给出 1->3->8->11->15->null2->null, 返回 1->2->3->8->11->15->null

class Solution {
public:
    ListNode * mergeTwoLists(ListNode * l1, ListNode * l2) {
        if(!l1) return l2;if(!l2) return l1;
        if(l1->val < l2->val) {
            l1->next = mergeTwoLists(l1->next, l2);return l1;
        } else {
            l2->next = mergeTwoLists(l2->next, l1);return l2;
        }
    }
};
class Solution {
public:
    /**
     * @param l1: ListNode l1 is the head of the linked list
     * @param l2: ListNode l2 is the head of the linked list
     * @return: ListNode head of linked list
     */
    ListNode * mergeTwoLists(ListNode * l1, ListNode * l2) {
        // write your code here
        if(l1 == NULL && l2 == NULL) return NULL;
        if(l1 == NULL) return l2;
        if(l2 == NULL) return l1;
        
        int val = 0;
        if(l1 -> val > l2 -> val)
        {
            val = l2 -> val;
            l2 = l2 -> next;
        }
        else
        {
            val = l1 -> val;
            l1 = l1 -> next;
        }
        ListNode *head = new ListNode(val);
        ListNode *n = head;
        
        while(l1 != NULL && l2 != NULL)
        {
            int val = 0;
            if(l1 -> val > l2 -> val)
            {
                val = l2 -> val;
                l2 = l2 -> next;
            }
            else
            {
                val = l1 -> val;
                l1 = l1 -> next;
            }
            ListNode *n2 = new ListNode(val);
            n -> next = n2;
            n = n -> next;
            n = n2;
        }
        while(l1 != NULL)
        {
            ListNode *n2 = new ListNode(l1 -> val);
            l1 = l1 -> next;
            n -> next = n2;
            n = n2;
        }
        while(l2 != NULL)
        {
            ListNode *n2 = new ListNode(l2 -> val);
            l2 = l2 -> next;
            n -> next = n2;
            n = n2;
        }
        n -> next = NULL;
        return head;
    }
};

 

167. 链表求和

你有两个用链表代表的整数,其中每个节点包含一个数字。数字存储按照在原来整数中相反的顺序,使得第一个数字位于链表的开头。写出一个函数将两个整数相加,用链表形式返回和。

样例

给出两个链表 3->1->5->null 和 5->9->2->null,返回 8->0->8->null

class Solution {
public:
    /**
     * @param l1: the first list
     * @param l2: the second list
     * @return: the sum list of l1 and l2 
     */
    ListNode * addLists(ListNode * l1, ListNode * l2) {
        // write your code here
        if(l2==NULL) return l1;
        ListNode *p=new ListNode(0);
        p->next=l1;
        int flag=0;
        while(p->next!=NULL){
            p->next->val+=l2->val+flag;
            if(p->next->val>=10){
                p->next->val-=10;
                flag=1;
            }
            else flag=0;
            p=p->next;
            l2=l2->next==NULL&&p->next!=NULL?new ListNode(0):l2->next;
        }
        while(l2!=NULL){
            p->next=new ListNode(l2->val+flag);
            if(p->next->val >= 10){
                p->next->val-=10;
                flag=1;
            }
            else flag=0;
            l2=l2->next;
            p=p->next;
        }
        if(flag==1) p->next=new ListNode(1);
        return l1;
    
    }
};

 

172. 删除元素

给定一个数组和一个值,在原地删除与值相同的数字,返回新数组的长度。

元素的顺序可以改变,并且对新的数组不会有影响。

样例

给出一个数组 [0,4,4,0,0,2,4,4],和值 4

返回 4 并且4个元素的新数组为[0,0,0,2]

class Solution {
public:
    /*
     * @param A: A list of integers
     * @param elem: An integer
     * @return: The new length after remove
     */
    int removeElement(vector<int> &A, int elem) {
        // write your code here
        if(A.size() == 0) return 0;
        for(int i = A.size()-1; i>=0; i--)
            if(A[i] == elem)
                A.erase(A.begin()+i);
        return A.size();
    }
};

 

173. 链表插入排序

用插入排序对链表排序

样例

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

class Solution {
public:
    ListNode* insertionSortList(ListNode* head) {
        ListNode dummy(0), *st = head; // st: st and nodes before st are sorted
        dummy.next = head;
        while (st) {
            if (st->next and st->next->val < st->val) {
                auto p = &dummy, q = st->next;
                while (p->next->val < st->next->val) // find insertion point
                    p = p->next;
                st->next = q->next;
                q->next = p->next;
                p->next = q;
            }
            else st = st->next;
        }
        return dummy.next;
    }
};

 

174. 删除链表中倒数第n个节点

给定一个链表,删除链表中倒数第n个节点,返回链表的头节点。

样例

给出链表1->2->3->4->5->null和 n = 2.

删除倒数第二个节点之后,这个链表将变成1->2->3->5->null.

挑战

O(n)时间复杂度

注意事项

链表中的节点个数大于等于n

输入测试数据 (每行一个参数)

class Solution {
public:
    /**
     * @param head: The first node of linked list.
     * @param n: An integer
     * @return: The head of linked list.
     */
    ListNode * removeNthFromEnd(ListNode * head, int n) {
        // write your code here
        ListNode *del=new ListNode(0);
        del->next=head;
        ListNode *temp=del;
        for(int i=0;i<n;i++){head=head->next;}
        while(head!=NULL){head=head->next;temp=temp->next;}
        temp->next=temp->next->next;
        return del->next;
    }
};

 

175. 翻转二叉树

翻转一棵二叉树

样例

  1         1
 / \       / \
2   3  => 3   2
   /       \
  4         4

挑战

递归固然可行,能否写个非递归的?

class Solution {
public:
    /**
     * @param root: a TreeNode, the root of the binary tree
     * @return: nothing
     */
    void invertBinaryTree(TreeNode * root) {
        // write your code here
        if(root)
        {
            swap(root -> left, root -> right);
            invertBinaryTree(root -> left);
            invertBinaryTree(root -> right);
        }
    }
};

 

372. Delete Node in a Linked List

给定一个单链表中的一个等待被删除的节点(非表头或表尾)。请在在O(1)时间复杂度删除该链表节点。

样例

Linked list is 1->2->3->4, and given node 3, delete the node in place 1->2->4

class Solution {
public:
    /*
     * @param node: the node in the list should be deletedt
     * @return: nothing
     */
    void deleteNode(ListNode * node) {
        // write your code here
        node -> val = node -> next -> val;
        node -> next = node -> next -> next;
    }
};

 

389. 判断数独是否合法

请判定一个数独是否有效。

该数独可能只填充了部分数字,其中缺少的数字用 . 表示。

样例

The following partially filed sudoku is valid.

Valid Sudoku

说明

什么是 数独

注意事项

一个合法的数独(仅部分填充)并不一定是可解的。我们仅需使填充的空格有效即可。

class Solution {
public:
    /*
     * @param board: the board
     * @return: whether the Sudoku is valid
     */
    bool isValidSudoku(vector<vector<char>> &board) {
     
       vector<vector<bool> > rows(9, vector<bool>(9, false));
    	vector<vector<bool> > cols(9, vector<bool>(9, false));
		vector<vector<bool> > blocks(9, vector<bool>(9, false));

		for (int i = 0; i < 9; ++i) {
			for (int j = 0; j < 9; ++j) {
				if (board[i][j] == '.') continue;
				int c = board[i][j] - '1';
				if (rows[i][c] || cols[j][c] || blocks[i - i % 3 + j / 3][c])
					return false;
				rows[i][c] = cols[j][c] = blocks[i - i % 3 + j / 3][c] = true;
			}
		}
		return true;  // write your code here
    }
};

 

407. 加一

给定一个非负数,表示一个数字数组,在该数的基础上+1,返回一个新的数组。

该数字按照数位高低进行排列,最高位的数在列表的最前面。

样例

给定 [1,2,3] 表示 123, 返回 [1,2,4].

给定 [9,9,9] 表示 999, 返回 [1,0,0,0].

输入测试数据 (每行一个参数)

class Solution {
public:
    /**
     * @param digits: a number represented as an array of digits
     * @return: the result
     */
    vector<int> plusOne(vector<int> &digits) {
        // write your code here
        digits.back() +=1;
        for(int i = digits.size()-1; i > 0; i--)
            if(digits[i] > 9)
            {
                digits[i] = digits[i] % 10;
                digits[i-1]++;
            }
        if(digits[0] > 9)
        {
            digits[0] = digits[0] % 10;
            digits.insert(digits.begin(),1);
        }
        return digits;
    }
};

 

408. 二进制求和

给定两个二进制字符串,返回他们的和(用二进制表示)。

样例

a = 11

b = 1

返回 100

class Solution {
public:
    /*
     * @param a: a number
     * @param b: a number
     * @return: the result
     */
    string addBinary(string &a, string &b) {
        string ret;

    	int m = a.size(), n = b.size();
		int i = m - 1, j = n - 1, val = 0;
		while (i > -1 || j > -1 || val)
		{
			if (i > -1)
				val += a[i--] - 48;
			if (j > -1)
				val += b[j--] - 48;

			ret = to_string(val % 2) + ret;
			val /= 2;
		}

		return ret;
    }
};

 

413. 反转整数

将一个整数中的数字进行颠倒,当颠倒后的整数溢出时,返回 0 (标记为 32 位整数)。

样例

给定 x = 123,返回 321

给定 x = -123,返回 -321

class Solution {
public:
    /**
     * @param n: the integer to be reversed
     * @return: the reversed integer
     */
    int reverseInteger(int x) {
        // write your code here
        long res = 0;
        while (x != 0) {
            res = res * 10 + x % 10;
            x /= 10;
        }
        return res > INT_MAX or res < INT_MIN ? 0 : res;
    }
};

 

415. 有效回文串

给定一个字符串,判断其是否为一个回文串。只考虑字母和数字,忽略大小写。

样例

"A man, a plan, a canal: Panama"是一个回文。

"race a car" 不是一个回文。

挑战

O(n) 时间复杂度,且不占用额外空间。

注意事项

你是否考虑过,字符串有可能是空字符串?这是面试过程中,面试官常常会问的问题。

在这个题目中,我们将空字符串判定为有效回文。

class Solution {
public:
    /**
     * @param s: A string
     * @return: Whether the string is a valid palindrome
     */
    bool isPalindrome(string &s) {
        if(s.size() == 0) return 1;
        for(int i = s.size()-1; i>=0; i--)
        {
            if((s[i] >= 65 && s[i] <=90)||(s[i] >= 97 && s[i] <= 122)|| (s[i] >= 48 && s[i] <= 57))
            {
                if(s[i] >= 65 && s[i] <=90)
                {
                    s[i] = 32 + s[i];
                }
            }
            else s.erase(s.begin()+i);
        }
        int i = 0; int j = 0;
        for(i = 0, j = s.size()-1; i<s.size()/2; i++, j--)
        {
            if(s[i] != s[j]) return false; 
        }
        return true;
    }
};

 

420. 报数

报数指的是,按照其中的整数的顺序进行报数,然后得到下一个数。如下所示:

1, 11, 21, 1211, 111221, ...

1 读作 "one 1" -> 11.

11 读作 "two 1s" -> 21.

21 读作 "one 2, then one 1" -> 1211.

给定一个整数 n, 返回 第 n 个顺序。

样例

给定 n = 5, 返回 "111221".

注意事项

整数的顺序将表示为一个字符串。

class Solution {
public:
    /*
     * @param n: the nth
     * @return: the nth sequence
     */
string countAndSay(int n) {
    if (n <= 0) return "";
	string res = "1";
	while (--n) {
		string cur = "";
		for (int i = 0; i < res.size(); ++i) {
			int cnt = 1;
			while (i + 1 < res.size() && res[i] == res[i + 1]) {
				++cnt;
				++i;
			}
			cur += to_string(cnt) + res[i];
		}
		res = cur;
	}
	return res;
}
};

 

422. 最后一个单词的长度

给定一个字符串, 包含大小写字母、空格' ',请返回其最后一个单词的长度。

如果不存在最后一个单词,请返回 0

样例

给定 s = "Hello World",返回 5

注意事项

一个单词的界定是,由字母组成,但不包含任何的空格。

class Solution {
public:
    /**
     * @param s: A string
     * @return: the length of last word
     */
    int lengthOfLastWord(string &s) {
        int result = 0;
        for(int i = s.length()-1;i>=0;i--){
            if(s[i]!=' '){
                result++;
            }else{
                if(result)
                    return result;
            }
        }
        return result;
    }
};

 

423. 有效的括号序列

给定一个字符串所表示的括号序列,包含以下字符: '(', ')''{''}''['and ']', 判定是否是有效的括号序列。

样例

括号必须依照 "()" 顺序表示, "()[]{}" 是有效的括号,但 "([)]"则是无效的括号。

class Solution {
public:
    /**
     * @param s: A string
     * @return: whether the string is a valid parentheses
     */
    bool isValidParentheses(string &s) {
        // write your code here
        std::stack<int> stack1;
        unordered_map<int, int> mapping = {{'(',')'},{'{', '}'}, {'[',']'}};
        for(int i = 0; s[i] != '\0'; i++)
        {
            if(s[i] == '('||s[i] == '{'||s[i] == '[')
                stack1.push(s[i]);
            else {
                if (stack1.empty() || mapping.find(stack1.top()) == mapping.end() || mapping[stack1.top()] != s[i]) {
                    return false;
                }
                stack1.pop();
            }
        }
        return stack1.size() == 0;
    }
};

 

433. 岛屿的个数

给一个01矩阵,求不同的岛屿的个数。

0代表海,1代表岛,如果两个1相邻,那么这两个1属于同一个岛。我们只考虑上下左右为相邻。

样例

在矩阵:

[
  [1, 1, 0, 0, 0],
  [0, 1, 0, 0, 1],
  [0, 0, 0, 1, 1],
  [0, 0, 0, 0, 0],
  [0, 0, 0, 0, 1]
]

中有 3 个岛.

输入测试数据 (每行一个参数)

class Solution{

    bool dfs(int i,int j,vector<vector<bool>> &grid)
	{
		if(i>=0&&i<grid.size()&&j>=0&&j<grid[i].size()&&grid[i][j]==true)
		{
			grid[i][j] = false;
			dfs(i-1,j,grid);
			dfs(i+1,j,grid);
			dfs(i,j-1,grid);
			dfs(i,j+1,grid);
			return true;
		}
		return false;
	}
public:	
	int numIslands(vector<vector<bool>> &grid) {
		int num = 0;
		for(int i=0;i<grid.size();i++)
		{
			for(int j=0;j<grid[i].size();j++)
			{
				if(dfs(i,j,grid))
					num++;
			}
		}
		return num;
	}
};

 

451. 两两交换链表中的节点

给一个链表,两两交换其中的节点,然后返回交换后的链表。

样例

给出 1->2->3->4, 你应该返回的链表是 2->1->4->3

挑战

你的算法只能使用常数的额外空间,并且不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。

输入测试数据 (每行一个参数)

class Solution {
public:
    /**
     * @param head: a ListNode
     * @return: a ListNode
     */
    ListNode * swapPairs(ListNode * head) {
        ListNode* dummy = new ListNode(-1);
        ListNode* prev = dummy;
        dummy->next = head;
        while (prev->next && prev->next->next) {
            ListNode* next = prev->next->next;
            prev->next->next = next->next;
            next->next = prev->next;
            prev->next = next;
            prev = next->next;
        }
        return dummy->next;
    }
};

 

453. 将二叉树拆成链表

将一棵二叉树按照前序遍历拆解成为一个假链表。所谓的假链表是说,用二叉树的 right 指针,来表示链表中的 next 指针。

样例

              1
               \
     1          2
    / \          \
   2   5    =>    3
  / \   \          \
 3   4   6          4
                     \
                      5
                       \
                        6

挑战

不使用额外的空间耗费。

注意事项

不要忘记将左儿子标记为 null,否则你可能会得到空间溢出或是时间溢出。

输入测试数据 (每行一个参数)

class Solution {
public:
    /**
     * @param root: a TreeNode, the root of the binary tree
     * @return: nothing
     */
    void flatten(TreeNode * root) {
        if (!root) return;
        auto rnode = root->right;
        flatten(root->left);
        root->right = root->left;
        root->left = NULL;
        while(root->right) root = root->right;
        root->right = rnode;
        flatten(rnode);
    }
};

 

469. Same Tree

检查两棵二叉树是否等价。等价的意思是说,首先两棵二叉树必须拥有相同的结构,并且每个对应位置上的节点上的数都相等。

样例

    1             1
   / \           / \
  2   2   and   2   2
 /             /
4             4

就是两棵等价的二叉树。

    1             1
   / \           / \
  2   3   and   2   3
 /               \
4                 4

就不是等价的。

class Solution {
public:
    /**
     * @param a: the root of binary tree a.
     * @param b: the root of binary tree b.
     * @return: true if they are identical, or false.
     */
    bool isIdentical(TreeNode * a, TreeNode * b) {
        // write your code here
        if(a== NULL && b == NULL)
            return true;
        if(a == NULL || b == NULL)
            return false;
        if(a->val != b->val)
            return false;
        return isIdentical(a->left, b->left) && isIdentical(a->right, b->right);
    }
};

 

480. 二叉树的所有路径

给一棵二叉树,找出从根节点到叶子节点的所有路径。

样例

给出下面这棵二叉树:

   1
 /   \
2     3
 \
  5

所有根到叶子的路径为:

[
  "1->2->5",
  "1->3"
]

输入测试数据 (每行一个参数)

vector<string> result;
class Solution {
public:
    string to_str(int x){stringstream os;os << x;return os.str();}
    vector<string> binaryTreePaths(TreeNode* root) {
        dfs(root,(string)"");
        return result;
    }
private:
    void dfs(TreeNode *root,string s){
        if(!root)  return;
        s+=to_str(root->val)+"->";
        if(!root->left && !root->right){
            result.push_back(s.substr(0,s.size()-2));
        }
      
        dfs(root->left,s);
        dfs(root->right,s);
    }
};

 

488. 快乐数

写一个算法来判断一个数是不是"快乐数"。

一个数是不是快乐是这么定义的:对于一个正整数,每一次将该数替换为他每个位置上的数字的平方和,然后重复这个过程直到这个数变为1,或是无限循环但始终变不到1。如果可以变为1,那么这个数就是快乐数。

样例

19 就是一个快乐数。

1^2 + 9^2 = 82
8^2 + 2^2 = 68
6^2 + 8^2 = 100
1^2 + 0^2 + 0^2 = 1

输入测试数据 (每行一个参数)

class Solution {
public:
    bool isHappy(int n) {
        while (n != 1 && n != 4) {
            int t = 0;
            while (n) {
                t += (n % 10) * (n % 10);
                n /= 10;
            }
            n = t;
        }
        return n == 1;
    }
};

 

491. 回文数

判断一个正整数是不是回文数。

回文数的定义是,将这个数反转之后,得到的数仍然是同一个数。

样例

11121112321 这些是回文数。

23321232 这些不是回文数。

注意事项

给的数一定保证是32位正整数,但是反转之后的数就未必了。

输入测试数据 (每行一个参数)

class Solution {
public:
    /**
     * @param num: a positive number
     * @return: true if it's a palindrome or false
     */
    bool isPalindrome(int num) {
        string s = to_string(num);
        string t = s;
        reverse(s.begin(), s.end());
        return s == t;
    }
};

 

514. 栅栏染色

我们有一个栅栏,它有n个柱子,现在要给柱子染色,有k种颜色可以染。
必须保证不存在超过2个相邻的柱子颜色相同,求有多少种染色方案。

样例

n = 3, k = 2, return 6

      post 1,   post 2, post 3
way1    0         0       1 
way2    0         1       0
way3    0         1       1
way4    1         0       0
way5    1         0       1
way6    1         1       0

注意事项

nk都是非负整数

输入测试数据 (每行一个参数)

class Solution {
public:
    int numWays(int n, int k) {
		int * store = new int[n];
		if (n == 1)
			return k;
		if (n == 2)
			return k * k;
		store[0] = k;
		store[1] = k * k;
		for (int i = 2; i < n; i++)
		{
			store[i] = (store[i - 1] + store[i - 2])*(k - 1);
		}
		return store[n - 1];
	}
};

 

517. 丑数

写一个程序来检测一个整数是不是丑数

丑数的定义是,只包含质因子 2, 3, 5的正整数。比如 6, 8 就是丑数,但是 14 不是丑数以为他包含了质因子 7。

样例

给出 num = 8,返回 true
给出 num = 14,返回 false

注意事项

可以认为 1 是一个特殊的丑数。

输入测试数据 (每行一个参数)

class Solution {
public:
    /**
     * @param num: An integer
     * @return: true if num is an ugly number or false
     */
    bool isUgly(int num) {
        if(num == 0) return false;
        // write your code here
        while(num % 2 == 0)
            num = num / 2;
        while(num % 3 == 0)
            num = num / 3;
        while(num % 5 == 0)
            num = num / 5;
        if(num == 1) return true;
        else return false;
    }
};

 

551. 嵌套列表的加权和

给一个嵌套的整数列表, 返回列表中所有整数由它们的深度加权后的总和. 每一个元素可能是一个整数或一个列表(其元素也可能是整数或列表)

样例

给出列表 [[1,1],2,[1,1]], 返回 10. (4个'1'的深度是 2, 1个'2'的深度是1, 4 * 1 * 2 + 1 * 2 * 1 = 10)
给出列表 [1,[4,[6]]], 返回 27. (1个 '1' 的深度是1, 1个 '4' 的深度是2, 以及1个 '6'的深度是3, 1 + 4 * 2 + 6 * 3 = 27)

class Solution {
public:
    int depthSum(const vector<NestedInteger>& nestedList) {
        // Write your code here
        return calculate(nestedList,1);
    }
    
    int calculate(const vector<NestedInteger>& nestedList,int count){
        int sum=0;
        for(int i=0;i<nestedList.size();i++){
            if(nestedList[i].isInteger()) sum+=nestedList[i].getInteger()*count;
            else sum+=calculate(nestedList[i].getList(),count+1);
        }
        return sum;
    }
};

 

655. Add Strings

以字符串的形式给出两个非负整数 num1 和 num2,返回 num1 和 num2的和。

样例

给定 num1 = "123",num2 = "45"
返回 "168"

注意事项

  • num1 和 num2 的长度都小于5100。
  • num1 和 num2 都只包含数字 0-9。
  • num1 和 num2 都不包含任何前导零。
  • 您不能使用任何内置的BigInteger库内的方法或直接将输入转换为整数。

输入测试数据 (每行一个参数)

class Solution {
public:
    /**
     * @param num1: a non-negative integers
     * @param num2: a non-negative integers
     * @return: return sum of num1 and num2
     */
    string addStrings(string &num1, string &num2) {
        // write your code here
        string num;
        int m = num1.size()-1; int n = num2.size()-1;
        int temp = 0;
        while(m>=0 || n >=0 || temp)
        {
            if(m>=0) temp = temp + num1[m--] - 48;
            if(n>=0) temp = temp + num2[n--] - 48; 
            num = to_string(temp % 10) + num;
            temp /= 10;
        }
        return num;
    }
};

 

828. 字模式

给定一个模式和一个字符串str,查找str是否遵循相同的模式。
这里遵循的意思是一个完整的匹配,在一个字母的模式和一个非空的单词str之间有一个双向连接的模式对应。

样例

给定模式= "abba", str = "dog cat cat dog",返回true。给定模式= "abba", str = "dog cat cat fish",返回false
给定模式= "aaaa", str = "dog cat cat dog",返回false。给定模式= "abba", str = "dog dog dog dog",返回false

注意事项

您可以假设模式只包含小写字母,而str包含由单个空间分隔的小写字母。

输入测试数据 (每行一个参数)

class Solution {
public:
    /**
     * @param pattern: a string, denote pattern string
     * @param str: a string, denote matching string
     * @return: an boolean, denote whether the pattern string and the matching string match or not
     */
    bool wordPattern(string &pattern, string &str) {
        // write your code here
      map<char,int>p1;
      map<string,int>p2;
      int i=0;
      int n=pattern.size();
      istringstream in(str);
      for(string word;in>>word;i++)
      {
          if(i==n||p1[pattern[i]]!=p2[word])
          return false;
          p1[pattern[i]]=p2[word]=i+1;
      }
      return true;
    }
};

 

888. 有效单词词广场

给定一个单词序列,检查它是否构成一个有效单词广场。
一个有效的单词广场满足:如果第k行和第k列读取相同的字符串,并且0≤k<max(numRows numColumns)

样例

给定
[
  "abcd",
  "bnrt",
  "crmy",
  "dtye"
]
返回 true

解释:
第一行和第一列都是“abcd”。
第二行和第二列都是“bnrt”。
第三行和第三列都是“crmy”。
第四行和第四列都是“dtye”。

因此,这是一个有效的单词广场.
给定
[
  "abcd",
  "bnrt",
  "crm",
  "dt"
]
返回 true

解释:
第一行和第一列都是“abcd”。
第二行和第二列都是“bnrt”。
第三行和第三列都是“crm”。
第四行和第四列都是“dt”。

因此,这是一个有效的单词广场.
给定
[
  "ball",
  "area",
  "read",
  "lady"
]
返回 false

解释:
第三行是 "read" 但是第三列是 "lead".

因此,这不是一个有效的单词广场.

注意事项

给定的单词数量至少为1,且不超过500
单词长度至少为1,不超过500
每个单词只包含小写英文字母a-z

输入测试数据 (每行一个参数)

class Solution {
public:
    /**
     * @param words: a list of string
     * @return: a boolean
     */
    bool validWordSquare(vector<string> &words) {
        // Write your code here
        for(int i = 0; i<words.size(); i++)
            for(int j = i; j<words[0].size(); j++)
                if(words[i][j] != words[j][i])
                    return false;
        return true;
    }
};

 

914. 翻转游戏

翻转游戏:给定一个只包含两种字符的字符串:+-,你和你的小伙伴轮流翻转"++"变成"--"。当一个人无法采取行动时游戏结束,另一个人将是赢家。

编写一个函数,计算字符串在一次有效移动后的所有可能状态。

样例

给定 s = "++++", 在一次有效移动后,它会变成下列状态之一:

[
  "--++",
  "+--+",
  "++--"
]

如果无法移动,则返回一个空列表[]

class Solution {
public:
    /**
     * @param s: the given string
     * @return: all the possible states of the string after one valid move
     */
    vector<string> generatePossibleNextMoves(string &s) {
        // write your code here
        vector<string> result;
        if(s.size() == 0) return result;
        for(int i = 0; i<s.size()-1; i++)
        {
            if(s[i] == '+'&&s[i+1] == '+')
            {
                string s1 = s;
                s1[i] = '-';
                s1[i+1] = '-';
                result.push_back(s1);
            }
        }
        return result;
    }
};

 

1017. Similar RGB Color

In the following, every capital letter represents some hexadecimal digit from 0to f.

The red-green-blue color "#AABBCC" can be written as "#ABC" in shorthand. For example, "#15c" is shorthand for the color "#1155cc".

Now, say the similarity between two colors "#ABCDEF" and "#UVWXYZ" is -(AB - UV)^2 - (CD - WX)^2 - (EF - YZ)^2.

Given the color "#ABCDEF", return a 7 character color that is most similar to #ABCDEF, and has a shorthand (that is, it can be represented as some "#XYZ")

样例

Input: color = "#09f166"
Output: "#11ee66"
Explanation:  
The similarity is -(0x09 - 0x11)^2 -(0xf1 - 0xee)^2 - (0x66 - 0x66)^2 = -64 -9 -0 = -73.
This is the highest among any shorthand color.

注意事项

  • color is a string of length 7.
  • color is a valid RGB color: for i > 0color[i] is a hexadecimal digit from 0 to f
  • Any answer which has the same (highest) similarity as the best answer will be accepted.
  • All inputs and outputs should use lowercase letters, and the output is 7 characters.

输入测试数据 (每行一个参数)

class Solution {
public:
    string similarRGB(string color) {
        for (int i = 1; i < 7; i += 2) {
            int num = stoi(color.substr(i, 2), nullptr, 16);
            int idx = num / 17 + (num % 17 > 8 ? 1 : 0);
            color[i] = color[i + 1] = (idx > 9) ? (idx - 10 + 'a') : (idx + '0');
        }
        return color;
    }
};

 

1032. Letter Case Permutation

Given a string S, we can transform every letter individually to be lowercase or uppercase to create another string. Return a list of all possible strings we could create.

样例

Input: S = "a1b2"
Output: ["a1b2", "a1B2", "A1b2", "A1B2"]

Input: S = "3z4"
Output: ["3z4", "3Z4"]

Input: S = "12345"
Output: ["12345"]

注意事项

S will be a string with length at most 12.
S will consist only of letters or digits

class Solution {
public:
  vector<string> letterCasePermutation(string S) {
    vector<string> ans;
    dfs(S, 0, ans);
    return ans;
  }
private:
  void dfs(string& S, int s, vector<string>& ans) {
    if (s == S.length()) {
      ans.push_back(S);
      return;      
    }
    dfs(S, s + 1, ans);    
    if (!isalpha(S[s])) return;          
    S[s] ^= (1 << 5);
    dfs(S, s + 1, ans);
    S[s] ^= (1 << 5);
  }
};

 

1042. Toeplitz Matrix

A matrix is Toeplitz if every diagonal from top-left to bottom-right has the same element.

Now given an M x N matrix, return True if and only if the matrix is Toeplitz.

样例

Example 1:

Input: matrix = [[1,2,3,4],[5,1,2,3],[9,5,1,2]]
Output: True
Explanation:
1234
5123
9512

In the above grid, the diagonals are "[9]", "[5, 5]", "[1, 1, 1]", "[2, 2, 2]", "[3, 3]", "[4]", and in each diagonal all elements are the same, so the answer is True.


Example 2:

Input: matrix = [[1,2],[2,2]]
Output: False
Explanation:
The diagonal "[1, 2]" has different elements.

注意事项

  1. matrix will be a 2D array of integers.
  2. matrix will have a number of rows and columns in range [1, 20].
  3. matrix[i][j] will be integers in range [0, 99].

输入测试数据 (每行一个参数)

class Solution {
public:
  bool isToeplitzMatrix(vector<vector<int>> &matrix) {
    int m = matrix.size();
    int n = matrix[0].size();
    for (int i = 0; i < m - 1; i++) {
      for (int j = 0; j < n - 1; j++) {
        if (matrix[i][j] != matrix[i + 1][j + 1])
          return false;
      }
    }
    return true;
  }
};

 

1046. Prime Number of Set Bits in Binary Representation

Given two integers L and R, find the count of numbers in the range [L, R](inclusive) having a prime number of set bits in their binary representation.

(Recall that the number of set bits an integer has is the number of 1s present when written in binary. For example, 21 written in binary is 10101 which has 3 set bits. Also, 1 is not a prime.)

样例

Example 1:

Input: L = 6, R = 10
Output: 4
Explanation:
6 -> 110 (2 set bits, 2 is prime)
7 -> 111 (3 set bits, 3 is prime)
9 -> 1001 (2 set bits , 2 is prime)
10->1010 (2 set bits , 2 is prime)

Example 2:

Input: L = 10, R = 15
Output: 5
Explanation:
10 -> 1010 (2 set bits, 2 is prime)
11 -> 1011 (3 set bits, 3 is prime)
12 -> 1100 (2 set bits, 2 is prime)
13 -> 1101 (3 set bits, 3 is prime)
14 -> 1110 (3 set bits, 3 is prime)
15 -> 1111 (4 set bits, 4 is not prime)

注意事项

1.LR will be integers L <= R in the range [1, 10^6].
2.R - L will be at most 10000.

class Solution {
public:
    int countPrimeSetBits(int L, int R) {
        unordered_set<int> p = {2,3,5,7,11,13,17,19};
        int res = 0;
        for (int i = L; i <= R; ++i) {
            int n = i, count = 0;
            while (n) {
                n = n & (n-1);
                count ++;
            }
            if (p.count(count)) res ++;
        }
        return res;
    }
};

 

1319. Contains Duplicate II

Given an array of integers and an integer k, find out whether there are two distinct indices i and j in the array such that nums[i] = nums[j] and the absolute difference between i and j is at most k.

样例

Given nums = [1,2,1], k = 0, return false.

输入测试数据 (每行一个参数)

class Solution {
public:
    /**
     * @param nums: the given array
     * @param k: the given number
     * @return:  whether there are two distinct indices i and j in the array such that nums[i] = nums[j] and the absolute difference between i and j is at most k
     */
    bool containsNearbyDuplicate(vector<int> &nums, int k) {
        // Write your code here
                std::unordered_map<int, int> m;
        for (int i = 0; i < nums.size(); ++i) {
            if (m.find(nums[i]) != m.end() && i - m[nums[i]] <= k) return true;
            else m[nums[i]] = i;
        }
        return false;
    }
};

 

1347. 尾随零

给定一个整数n,返回n!(n的阶乘)的尾随零的个数。

注意事项

您的解法时间复杂度应为对数级别。

class Solution {
public:
    /**
     * @param n: a integer
     * @return: return a integer
     */
    int trailingZeroes(int n) {
        // write your code here
        int ret = 0;
        while(n)
        {
            ret += n/5;
            n /= 5;
        }
        return ret;
    }
};

 

1350. Excel表列标题

给定一个正整数,返回相应的列标题,如Excel表中所示。

样例

1 -> A
2 -> B
3 -> C
...
26 -> Z
27 -> AA
28 -> AB 

输入测试数据 (每行一个参数)

class Solution {
public:
    /**
     * @param n: a integer
     * @return: return a string
     */
    string convertToTitle(int n) {
        // write your code here
        string excel;
        while(n > 0)
        {
            excel =  char((n-1) % 26 + 65) + excel;
            n = (n -1) / 26;
        }
        return excel;
    }
};

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值