每日一道算法题之-字符串、动态规划、数组

第 k 大的数
Find the kth largest element in an unsorted array. Note that it is the kth largest element in the sorted order, not the kth distinct element.
For example,
Given [3,2,1,5,6,4] and k = 2, return 5.
Note:
You may assume k is always valid, 1 ≤ k ≤ array's length.

class Solution {
public:   
    inline int left(int idx) {
        return (idx << 1) + 1;
    }
    inline int right(int idx) {
        return (idx << 1) + 2;
    }
    void max_heapify(vector<int>& nums, int idx) {
        int largest = idx;
        int l = left(idx), r = right(idx);
        if (l < heap_size && nums[l] > nums[largest]) largest = l;
        if (r < heap_size && nums[r] > nums[largest]) largest = r;
        if (largest != idx) {
            swap(nums[idx], nums[largest]);
            max_heapify(nums, largest);
        }
    }
    void build_max_heap(vector<int>& nums) {
        heap_size = nums.size();
        for (int i = (heap_size >> 1) - 1; i >= 0; i--)
            max_heapify(nums, i);
    }
    int findKthLargest(vector<int>& nums, int k) {
        build_max_heap(nums);
        for (int i = 0; i < k; i++) {
            swap(nums[0], nums[heap_size - 1]);
            heap_size--;
            max_heapify(nums, 0);
        }
        return nums[heap_size];
    }
private:
    int heap_size;
}

找数组中出现次数超过一半的数字04.14
数组中有一个数字出现次数超过数组长度的一半,请找出这个数字。例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。
由于数字2在数组中出现了5次,超过数组长度一半,因此输出2

int findNumber(std::vector<int> v){  
    std::stack<int> stack = std::stack<int>();
    for (int i = 0; i < v.size(); ++i) {
        if (stack.empty() || stack.top() == v[i]) {
            stack.push(v[i]);
        }
        else{
            stack.pop();
        }
    }
    return stack.top();
}

旋转数组求查找某个值是否存在04.12
Suppose an array sorted in ascending order is rotated at some pivot unknown to you beforehand.
(i.e., 0 1 2 4 5 6 7 might become 4 5 6 7 0 1 2).
You are given a target value to search. If found in the array return its index, otherwise return -1.
You may assume no duplicate exists in the array.

public static int search(int n,int[] array){  
        int low = 0;          
        int high = array.length-1;  
        while(low<=high){  
            int middle = (low+high)/2;  
            if(array[middle]==n) return middle;  
            if(array[middle]>array[low]){  //left is order  
                if(n<=array[middle]&&n>=array[low]){  
                    high = middle-1;  
                }else {  
                    low = middle+1;  
                }  
            }else {           
                if(n>=array[middle]&&n<=array[high]){  
                    low = middle+1;  
                }else {  
                    high = middle-1;  
                }  
            }  
        }  
        return -1;    
    } 

旋转数组求最小值04.10
Suppose an array sorted in ascending order is rotated at some pivot unknown to you beforehand.
(i.e., 0 1 2 4 5 6 7 might become 4 5 6 7 0 1 2).
Find the minimum element.
You may assume no duplicate exists in the array.

int findMin(vector<int> &num) {
        int start=0,end=num.size()-1;
        while (start<end) {
            if (num[start]<num[end])
                return num[start];
            
            int mid = (start+end)/2;
            
            if (num[mid]>=num[start]) {
                start = mid+1;
            } else {
                end = mid;
            }
        }
        return num[start];
    }

求两个不等长、有序数组的中位数04.09
There are two sorted arrays nums1 and nums2 of size m and n respectively.
Find the median of the two sorted arrays. The overall run time complexity should be O(log (m+n)).
Example:
nums1 = [1, 2]
nums2 = [3, 4]
The median is (2 + 3)/2 = 2.5

 double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
    int N1 = nums1.size();
    int N2 = nums2.size();
    if (N1 < N2) return findMedianSortedArrays(nums2, nums1);   // Make sure A2 is the shorter one.
    
    if (N2 == 0) return ((double)nums1[(N1-1)/2] + (double)nums1[N1/2])/2;  // If A2 is empty
    
    int lo = 0, hi = N2 * 2;
    while (lo <= hi) {
        int mid2 = (lo + hi) / 2;   // Try Cut 2 
        int mid1 = N1 + N2 - mid2;  // Calculate Cut 1 accordingly
        
        double L1 = (mid1 == 0) ? INT_MIN : nums1[(mid1-1)/2];  // Get L1, R1, L2, R2 respectively
        double L2 = (mid2 == 0) ? INT_MIN : nums2[(mid2-1)/2];
        double R1 = (mid1 == N1 * 2) ? INT_MAX : nums1[(mid1)/2];
        double R2 = (mid2 == N2 * 2) ? INT_MAX : nums2[(mid2)/2];
        
        if (L1 > R2) lo = mid2 + 1;     // A1's lower half is too big; need to move C1 left (C2 right)
        else if (L2 > R1) hi = mid2 - 1;    // A2's lower half too big; need to move C2 left.
        else return (max(L1,L2) + min(R1, R2)) / 2; // Otherwise, that's the right cut.
    }
    return -1;
} 

实现简单的正则表达式匹配04.08
Implement regular expression matching with support for '.' and ''.
'.' Matches any single character.
'
' Matches zero or more of the preceding element.
The matching should cover the entire input string (not partial).

class Solution {
public:
    bool isMatch(string s, string p) {
        int m = s.length(), n = p.length(); 
        vector<vector<bool> > dp(m + 1, vector<bool> (n + 1, false));
        dp[0][0] = true;
        for (int i = 0; i <= m; i++)
            for (int j = 1; j <= n; j++)
                if (p[j - 1] == '*')
                    dp[i][j] = dp[i][j - 2] || (i > 0 && (s[i - 1] == p[j - 2] || p[j - 2] == '.') && dp[i - 1][j]);
                else dp[i][j] = i > 0 && dp[i - 1][j - 1] && (s[i - 1] == p[j - 1] || p[j - 1] == '.');
        return dp[m][n];
    }
};

连续子数组的最大和04.07
Find the contiguous subarray within an array (containing at least one number) which has the largest sum.
For example, given the array [-2,1,-3,4,-1,2,1,-5,4],
the contiguous subarray [4,-1,2,1] has the largest sum = 6.

public int maxSubArray(int[] A) {
        int n = A.length;
        int[] dp = new int[n];//dp[i] means the maximum subarray ending with A[i];
        dp[0] = A[0];
        int max = dp[0];
        
        for(int i = 1; i < n; i++){
            dp[i] = A[i] + (dp[i - 1] > 0 ? dp[i - 1] : 0);
            max = Math.max(max, dp[i]);
        }
        return max;
}

解题思路,从前往后的顺序,并不知道后面新加入的部分和是否会 >0,可以把这道动态规划的子问题的格式更改为:maxSubArray(int A [],int i)),这意味着A [0:i]的maxSubArray必须具有A [i]作为结束元素。我们可以判断知道A [i]之前连续元素的和的最大值。从而解决整个数组的连续子数组的最大和问题。

翻转字符串04.06
Given an input string, reverse the string word by word.
For example,Given s = "the sky is blue",return "blue is sky the".

void reverseWords(string &s) {
    reverse(s.begin(), s.end());
    int storeIndex = 0;
    for (int i = 0; i < s.size(); i++) {
        if (s[i] != ' ') {
            if (storeIndex != 0) s[storeIndex++] = ' ';
            int j = i;
            while (j < s.size() && s[j] != ' ') { s[storeIndex++] = s[j++]; }
            reverse(s.begin() + storeIndex - (j - i), s.begin() + storeIndex);
            i = j;
        }
    }
    s.erase(s.begin() + storeIndex, s.end());
}

字符串全排列04.05
Implement atoi to convert a string to an integer.consider all possible input cases.
用C++写一个函数, 如 Foo(const char *str), 打印出 str 的全排列, 如 abc 的全排列: abc, acb, bca, dac, cab, cab
思路:全排列就是从第一个数字起每个数分别与它后面的数字交换
#include <stdio.h>
#include <string.h>
void Swap(char *a, char *b)
{
char t = *a;
*a = *b;
*b = t;
}
//k表示当前选取到第几个数,m表示共有多少数.
void AllRange(char *pszStr, int k, int m)
{
if (k == m)
{
static int s_i = 1;
printf(" 第%3d个排列\t%s\n", s_i++, pszStr);
}
else {
for (int i = k; i <= m; i++) //第i个数分别与它后面的数字交换就能得到新的排列
{
Swap(pszStr + k, pszStr + i);
AllRange(pszStr, k + 1, m);
Swap(pszStr + k, pszStr + i);
}
}
}
void Foo(char *pszStr)
{
AllRange(pszStr, 0, strlen(pszStr) - 1);
}
int main()
{
printf(" 全排列的递归实现\n");
printf(" --by MoreWindows( http://blog.csdn.net/MoreWindows )--\n\n");
char szTextStr[] = "123";
printf("%s的全排列如下:\n", szTextStr);
Foo(szTextStr);
return 0;
}
输出:
123的全排列如下:
第 1个排列 123
第 2个排列 132
第 3个排列 213
第 4个排列 231
第 5个排列 321
第 6个排列 312

去掉重复的全排列的递归实现
思路:去重的全排列就是从第一个数字起每个数分别与它后面非重复出现的数字交换

//去重全排列的递归实现  
 #include <stdio.h>  
 #include <string.h>  
 void Swap(char *a, char *b)  
{  
    char t = *a;  
    *a = *b;  
    *b = t;  
}  
//在pszStr数组中,[nBegin,nEnd)中是否有数字与下标为nEnd的数字相等  
bool IsSwap(char *pszStr, int nBegin, int nEnd)  
{  
    for (int i = nBegin; i < nEnd; i++)  
        if (pszStr[i] == pszStr[nEnd])  
            return false;  
    return true;  
}  
//k表示当前选取到第几个数,m表示共有多少数.  
void AllRange(char *pszStr, int k, int m)  
{  
    if (k == m)  
    {  
        static int s_i = 1;  
        printf("  第%3d个排列\t%s\n", s_i++, pszStr);  
    }  
    else  
    {  
        for (int i = k; i <= m; i++) //第i个数分别与它后面的数字交换就能得到新的排列  
        {  
            if (IsSwap(pszStr, k, i))  
            {  
                Swap(pszStr + k, pszStr + i);  
                AllRange(pszStr, k + 1, m);  
                Swap(pszStr + k, pszStr + i);  
            }  
        }  
    }  
}  
void Foo(char *pszStr)  
{  
    AllRange(pszStr, 0, strlen(pszStr) - 1);  
}  
int main()  
{  
    printf("         去重全排列的递归实现\n");  
    printf("  --by MoreWindows( http://blog.csdn.net/MoreWindows )--\n\n");  
    char szTextStr[] = "122";  
    printf("%s的全排列如下:\n", szTextStr);  
    Foo(szTextStr);  
    return 0;  
}  

[字符串转数字04.04]?(https://leetcode.com/problems/string-to-integer-atoi/#/description)
Implement atoi to convert a string to an integer.consider all possible input cases.

int myAtoi(string str) {
  long result = 0;
  int indicator = 1;
  for(int i = 0; i<str.size();)
  {
      i = str.find_first_not_of(' ');
      if(str[i] == '-' || str[i] == '+')
        indicator = (str[i++] == '-')? -1 : 1;
      while('0'<= str[i] && str[i] <= '9') 
      {
        result = result*10 + (str[i++]-'0');
        if(result*indicator >= INT_MAX) return INT_MAX;
        if(result*indicator <= INT_MIN) return INT_MIN;                
      }
      return result*indicator;
  }
}

最长无重复子串04.03
Given a string, find the length of the longest substring without repeating characters.

int lengthOfLongestSubstring(string s) {  
    vector<int> dict(256, -1);  
    int maxLen = 0, start = -1;  
    for (int i = 0; i != s.length(); i++) {  
        if (dict[s[i]] > start)  
            start = dict[s[i]];  
        dict[s[i]] = i;  
        maxLen = max(maxLen, i - start);  
    }  
    return maxLen;  
}

最长回文字符串04.02
Given a string s, find the longest palindromic substring in s. You may assume that the maximum length of s is 1000.Example:Input: "babad" Output: "bab"

string longestPalindrome(string s) {
   if (s.empty()) return "";
   if (s.size() == 1) return s;
   int min_start = 0, max_len = 1;
   for (int i = 0; i < s.size();) {
       if (s.size() - i <= max_len / 2) break;
       int j = i, k = i;
       while (k < s.size()-1 && s[k+1] == s[k]) ++k;
       i = k+1;
       while (k < s.size()-1 && j > 0 && s[k + 1] == s[j - 1]) { ++k; --j; } 
       int new_len = k - j + 1;
       if (new_len > max_len) { min_start = j; max_len = new_len; }
    }
    return s.substr(min_start, max_len);
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,214评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,307评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,543评论 0 341
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,221评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,224评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,007评论 1 284
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,313评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,956评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,441评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,925评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,018评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,685评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,234评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,240评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,464评论 1 261
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,467评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,762评论 2 345

推荐阅读更多精彩内容