LeetCode题解(四)

LeetCode题解(四)

Remove Duplicates from Sorted Array

Given a sorted array, remove the duplicates in place such that each element appear only once and return the new length.

Do not allocate extra space for another array, you must do this in place with constant memory.

For example,
Given input array nums = [1,1,2],

Your function should return length = 2, with the first two elements of nums being 1 and 2 respectively. It doesn’t matter what you leave beyond the new length.

int removeDuplicates(int* nums, int numsSize) {
    if (!nums || !numsSize)
        return 0;

    int idx = 0;
    for (int i = 1; i < numsSize; ++i)
        if (nums[idx] != nums[i])
            nums[++idx] = nums[i];

    return idx + 1;  
}

Two Sum

Given an array of integers, return indices of the two numbers such that they add up to a specific target.

You may assume that each input would have exactly one solution.

Example:

Given nums = [2, 7, 11, 15], target = 9,

Because nums[0] + nums[1] = 2 + 7 = 9,
return [0, 1].

UPDATE (2016/2/13):
The return format had been changed to zero-based indices. Please read the above updated description carefully.

class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) {
        vector<int> result;
        unordered_map<int, int> hash;
        for (int i = 0; i < nums.size(); ++i)
            hash[nums[i]] = i;

        for (int i = 0; i < nums.size(); ++i) {
            int nextEle = target - nums[i];
            if (hash.find(nextEle) != hash.end() && hash[nextEle] > i) {
                result.push_back(i);
                result.push_back(hash[nextEle]);
                break;
            }
        }

        return result;
    }
};

Add Two Numbers

You are given two linked lists representing two non-negative numbers. The digits are stored in reverse order and each of their nodes contain a single digit. Add the two numbers and return it as a linked list.

Input: (2 -> 4 -> 3) + (5 -> 6 -> 4)
Output: 7 -> 0 -> 8

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
struct ListNode* addTwoNumbers(struct ListNode* l1, struct ListNode* l2) {
    typedef struct ListNode Node;   
    Node* result;
    Node* node = (Node*)malloc(sizeof(Node));
    node->next = NULL;
    result = node;
    int tmp = 0;
    while (l1 != NULL && l2 != NULL) {
        Node* tmpNode = (Node*)malloc(sizeof(Node));
        tmpNode->val = (l1->val + l2->val + tmp) % 10; 
        tmp = (l1->val + l2->val + tmp) / 10;
        l1 = l1->next;
        l2 = l2->next;
        node->next = tmpNode;
        node = node->next;
    }

    while (l1 != NULL) {
        Node* tmpNode = (Node*)malloc(sizeof(Node));
        tmpNode->val = (l1->val + tmp) % 10;
        tmp = (l1->val + tmp) / 10;
        l1 = l1->next;
        node->next = tmpNode;
        node = node->next;
    }

    while (l2 != NULL) {
        Node* tmpNode = (Node*)malloc(sizeof(Node));
        tmpNode->val = (l2->val + tmp) % 10;
        tmp = (l2->val + tmp) / 10;
        l2 = l2->next;
        node->next = tmpNode;
        node = node->next;
    }

    node->next = NULL;

    if (tmp != 0) {
        Node* tmpNode = (Node*)malloc(sizeof(Node));
        tmpNode->val = tmp;
        tmpNode->next = NULL;
        node->next = tmpNode;
    }

    node = result;
    result = result->next;
    free(node);
    return result;
}

Longest Substring Without Repeating Characters

Given a string, find the length of the longest substring without repeating characters.

Examples:

Given “abcabcbb”, the answer is “abc”, which the length is 3.

Given “bbbbb”, the answer is “b”, with the length of 1.

Given “pwwkew”, the answer is “wke”, with the length of 3. Note that the answer must be a substring, “pwke” is a subsequence and not a substring.

int lengthOfLongestSubstring(char* s) {
    int len = strlen(s);
    const int CHAR_NUM = 128;
    char base = (char)0;
    int record[CHAR_NUM];
    for (int i = 0; i < CHAR_NUM; ++i)
        record[i] = -1;
    int maxLen = 0;
    int curPos = 0;
    for (int i = 0; i < len; ++i) {
        if (record[s[i] - base] >= curPos) {
            maxLen = i - curPos > maxLen ? i - curPos : maxLen;
            curPos = record[s[i] - base] + 1;
        }
        record[s[i] - base] = i;
    }

    return len - curPos > maxLen ? len - curPos : maxLen;  
}

Median of Two Sorted Arrays

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 1:

nums1 = [1, 3]
nums2 = [2]

The median is 2.0

Example 2:

nums1 = [1, 2]
nums2 = [3, 4]

The median is (2 + 3)/2 = 2.5

double findMedianSortedArrays(int* nums1, int nums1Size, int* nums2, int nums2Size) {
    int m = (nums1Size + nums2Size) / 2 + 1;
    int tmp[m];
    int i = 0;
    int j = 0;
    for (int k = 0; k < m; ++k) {
        if (i >= nums1Size) {
            memcpy(tmp + k, nums2 + j, sizeof(int) * (m - k));
            break;
        } else if (j >= nums2Size) {
            memcpy(tmp + k, nums1 + i, sizeof(int) * (m - k));
            break;
        }
        tmp[k] = nums1[i] < nums2[j] ? nums1[i++] : nums2[j++];
    }

    for (int k = 0; k < m; ++k)
        printf("%d ", tmp[k]);
    if ((nums1Size + nums2Size) % 2) return tmp[m - 1];
    else return (tmp[m-1] + tmp[m - 2]) / 2.0;
}

Longest Palindromic Substring

Given a string S, find the longest palindromic substring in S. You may assume that the maximum length of S is 1000, and there exists one unique longest palindromic substring.

char* longestPalindrome(char* s) {
    int len;
    if (!s || (len = strlen(s)) < 2) return s;

    char* sCopy = (char*)malloc(sizeof(char) * (len + 2));
    sCopy[0] = '\0';
    sCopy = sCopy + 1;
    strcpy(sCopy, s);
    int maxLen = 0;
    char* curPos = sCopy;
    char* head = sCopy;
    char* end = sCopy;
    for (int i = 0; i < len; ++i) {
        head = sCopy + i;
        end = sCopy + i + 1;
        if (*head != *end && *(head - 1) != *end)
            continue;
        else {
            while (*end && *head == *end) {
                if (end - head > maxLen) {
                    maxLen = end - head; 
                    curPos = head;
                }
                end += 1;
            }

            end = sCopy + i + 1;
            while (*head && *end && *head == *end) {
                if (end  - head > maxLen) {
                     maxLen = end - head;
                     curPos = head;
                }
                head -= 1;
                end += 1;
            }

            head = sCopy + i - 1;
            end = sCopy + i + 1;
            while (*head && *end && *head == *end) {
                if (end - head > maxLen) {
                     maxLen = end - head;
                     curPos = head;
                }
                head -= 1;
                end += 1;
            }
        }
    }

    //printf("test: %d, %c, %c\n",maxLen, *curPos, *(curPos + maxLen));
    sCopy = sCopy - 1;
    memmove(sCopy, curPos, sizeof(char) * (maxLen + 1));
    *(sCopy + maxLen + 1) = '\0'; 
    return sCopy;
}

Regular Expression Matching

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).

The function prototype should be:
bool isMatch(const char *s, const char *p)

Some examples:
isMatch("aa","a") → false
isMatch("aa","aa") → true
isMatch("aaa","aa") → false
isMatch("aa", "a*") → true
isMatch("aa", ".*") → true
isMatch("ab", ".*") → true
isMatch("aab", "c*a*b") → true
bool isMatch(char* s, char* p) {
    if (*p == '\0') return *s == '\0';
    if (*(p + 1) != '*') {
        if(*p == *s || (*p == '.' && *s != '\0'))
            return isMatch(s + 1, p + 1);
        else 
            return false;
    } else {
        while (*p == *s || (*p == '.' && *s != '\0')) {
            if (isMatch(s, p + 2))
                return true;
            s++;
        }

        return isMatch(s, p + 2);
    }    
}

Container With Most Water

Given n non-negative integers a1, a2, …, an, where each represents a point at coordinate (i, ai). n vertical lines are drawn such that the two endpoints of line i is at (i, ai) and (i, 0). Find two lines, which together with x-axis forms a container, such that the container contains the most water.

Note: You may not slant the container.


#define MIN(a, b) (((a)<(b))?(a):(b))
#define MAX(a, b) (((a)<(b))?(b):(a))

int maxArea(int* height, int heightSize) {
    int result = INT_MIN;
    int a1 = 0;
    int a2 = heightSize - 1;
    while (a1 < a2) {
        int area = (MIN(height[a1], height[a2])) * (a2 - a1);
        result = MAX(result, area);
        if (height[a1] <= height[a2])
            ++a1;
        else
            --a2;
    }

    return result;
}

Integer to Roman

Given an integer, convert it to a roman numeral.

Input is guaranteed to be within the range from 1 to 3999.

char* copy(char* dst, const char* src) {
    while (*src)
        *dst++ = *src++;
    return dst;
}

char* intToRoman(int num) {
    char* result = (char*)malloc(sizeof(char) * 16);
    memset(result, '\0', sizeof(char) * 16);

    const int base[] = {
        1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1
    };
    const char* symbol[] = {
        "M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", 
        "IX", "V", "IV", "I"
    };

    char* tmp = result;
    for (int i = 0; num > 0; ++i) {
        int count = num / base[i];
        num = num % base[i];
        while (count--)
            tmp = copy(tmp, symbol[i]);
    }

    return result;
}

Longest Common Prefix

Write a function to find the longest common prefix string amongst an array of strings.

char* longestCommonPrefix(char** strs, int strsSize) {
    if (!strs || !strs[0]) return calloc(1, sizeof(char));

    int len = strlen(strs[0]);
    for (int i = 1; i < strsSize; ++i) {
        if (!strs[i]) return calloc(1, sizeof(char));
        for (int j = 0; j < len; ++j)
            if (!strs[i][j] || strs[i][j] != strs[0][j]) {
                len = j;
                break;
        }
    }

    char* result = (char*)malloc(sizeof(char) * (len + 1));
    result[len] = '\0';
    return memmove(result, strs[0], sizeof(char) * len);   
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值