LeetCode题解(C/C++、JAVA)

(注:每一条目中第一种为C/C++的题解,第二种为Java的题解)

1 两数之和(Two Sum)

/**
 * Note: The returned array must be malloced, assume caller calls free().
 */
int* twoSum(int* nums, int numsSize, int target) 
{
    int *res = (int*)malloc(sizeof(int)*2);
    for(int i = 0;i < numsSize-1;i++)
    {
        for(int j = i+1;j < numsSize;j++)
        {
            if(nums[i]+nums[j] == target)
            {
                res[0] = i;
                res[1] = j;
                return res;
            }
        }
    }
    
    return res; 
}
class Solution {
    public int[] twoSum(int[] nums, int target) {
        HashMap<Integer, Integer> m = new HashMap<Integer, Integer>();
        int[] res = new int[2];
        for(int i = 0;i < nums.length;i ++)
        {
            m.put(nums[i], i);
        }
        for(int i = 0;i < nums.length;i ++)
        {
            int t = target - nums[i];
            if(m.containsKey(t) && m.get(t) != i)
            {
                res[0] = i;
                res[1] = m.get(t);
                break;
            }
        }
        
        return res;
    }
}

2. 两数相加

struct ListNode* addTwoNumbers(struct ListNode* l1, struct ListNode* l2) 
{
    struct ListNode *head = (struct ListNode*)malloc(sizeof(struct ListNode)),*tail = head;//建立空的头结点
    int carry = 0;
    for(;l1 && l2;l1 = l1->next,l2 = l2->next)
    {
        int sum = l1->val + l2->val + carry;
        if(sum > 9)
        {
            sum -= 10;
            carry = 1;
        }
        else
        {
            carry = 0;
        }
        tail->next = (struct ListNode*)malloc(sizeof(struct ListNode));
        tail = tail->next;
        tail->val = sum;
    }
    //取两个链表较长的一个剩余部分
    l1 = l1 ? l1 : l2;
    for(;l1;l1 = l1->next)
    {
        int sum = l1->val + carry;
        if(sum > 9)
        {
            sum -= 10;
            carry = 1;
        }
        else
        {
            carry = 0;
        }
        tail->next = (struct ListNode*)malloc(sizeof(struct ListNode));
        tail = tail->next;
        tail->val = sum;
    }
    //如果还有进位,再分配一个节点
    if(carry)
    {
        tail->next = (struct ListNode*)malloc(sizeof(struct ListNode));
        tail = tail->next;
        tail->val = 1;
    }
    //链表指向空节点,即结束
    tail->next = NULL;
    //将空的头结点释放,从第二个节点返回
    tail = head;
    head = head->next;
    //c语言注意释放
    free(tail);
    return head;
}
/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
    public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
        ListNode l3 = new ListNode(0);
        ListNode result = l3;
        int carry = 0;
        while(l1 != null || l2 != null) //l1与l2有一个不为空,则在他们结尾处补0,而后逐位相加即可
        {
            int a = l1 == null ? 0 : l1.val;
            int b = l2 == null ? 0 : l2.val;
            if(a + b + carry <= 9)
            {
                result.next = new ListNode(a + b + carry);
                carry = 0;
            }
            else
            {
                result.next = new ListNode((a + b + carry) % 10);
                carry = 1;
            }
            result = result.next;
            if(l1 != null)
            {
                l1 = l1.next;
            }
            if(l2 != null)
            {
                l2 = l2.next;
            }
        }
        if(carry == 1)  //不要忘记两个数的最高位相加之后有可能会有进位,需要将此进位计算在内
        {
            result.next = new ListNode(carry);
        }
        return l3.next;  /*此处l3的链表形式为l3->result,所以当返回l3.next时,才能输出正确答案[7,0,8],此处要是返回l3,则输出的是[0,7,0,8];要是返回的result,则输出的是result指向的当前节点值[8];要是返回的是result.next,则输出的是result当前节点的下一个节点值[]*/
    }
}

3. 无重复字符的最长子串

class Solution {
public:
    int lengthOfLongestSubstring(string s) 
    {
        /*这里建立一个256位大小的整型数组来代替HashMap,这样做的原因是ASCII表共能表示256个字符,所以可以记录所有字符,然后我们需要定义两个变量res和left,其中res用来记录最长无重复子串的长度,left指向该无重复子串左边的起始位置,然后我们遍历整个字符串,对于每一个遍历到的字符,如果哈希表中该字符串对应的值为0,说明没有遇到过该字符,则此时计算最长无重复子串,i - left +1,其中i是最长无重复子串最右边的位置,left是最左边的位置,还有一         种情况也需要计算最长无重复子串,就是当哈希表中的值小于left,这是由于此时出现过重复的字符,left的位置更新了,如果又遇到了新的字符,就要重新计算 最长无重复子串。最后每次都要在哈希表中将当前字符对应的值赋值为i+1。*/
        int m[256] = {0}, res = 0, left = 0;
        for (int i = 0; i < s.size(); ++i)    //string类型的变量不可以用strlen()直接获取其长度,需要使用s.size()或者strlen(s.c_str())
        {
            if (m[s[i]] == 0 || m[s[i]] < left ) 
            {
                res = max(res, i - left + 1);
            } 
            else 
            {
                left = m[s[i]];
            }
            m[s[i]] = i + 1;
        }
        return res;
    }
};
class Solution {
    public int lengthOfLongestSubstring(String s) {
        int result = 0;
        HashMap<Character, Integer> res = new HashMap<Character, Integer>();
        for(int start = 0, end = 0;end < s.length();end ++)
        {
            char tmp = s.charAt(end);
            if(res.containsKey(tmp))
            {
                start = Math.max(res.get(tmp), start);
            }
            
            result = Math.max(end - start + 1, result);
            res.put(s.charAt(end), end + 1);
        }
        return result;
    }
}

5. 最长回文子串

class Solution {
public:
    string longestPalindrome(string s) 
    {
        /*动态规划的方法
        int dp[s.size()][s.size()] = {0}; 
        int left,right,len = 0;
        for (int i = 0; i < s.size(); ++i) {
            for (int j = 0; j < i; ++j) {
                dp[j][i] = (s[i] == s[j] && (i - j < 2 || dp[j + 1][i - 1]));
                if (dp[j][i] && len < i - j + 1) {
                    len = i - j + 1;
                    left = j;
                    right = i;
                }
            }
            dp[i][i] = 1;
        }
        return s.substr(left, right - left + 1);*/
        
        //马拉车算法(待深入理解)
        string t ="$#";
        for (int i = 0; i < s.size(); ++i) {
            t += s[i];
            t += '#';
        }
        int p[t.size()] = {0}, id = 0, mx = 0, resId = 0, resMx = 0;
        for (int i = 0; i < t.size(); ++i) {
            p[i] = mx > i ? min(p[2 * id - i], mx - i) : 1;
            while (t[i + p[i]] == t[i - p[i]]) ++p[i];
            if (mx < i + p[i]) {
                mx = i + p[i];
                id = i;
            }
            if (resMx < p[i]) {
                resMx = p[i];
                resId = i;
            }
        }
        return s.substr((resId - resMx) / 2, resMx - 1);
    }
};
class Solution {
public String longestPalindrome(String s) {
    if (s == null || s.length() < 1) return "";
    int start = 0, end = 0;
    for (int i = 0; i < s.length(); i++) {
        int len1 = expandAroundCenter(s, i, i);
        int len2 = expandAroundCenter(s, i, i + 1);
        int len = Math.max(len1, len2);
        if (len > end - start) {
            start = i - (len - 1) / 2;
            end = i + len / 2;
        }
    }
    return s.substring(start, end + 1);
}

private int expandAroundCenter(String s, int left, int right) {
    int L = left, R = right;
    while (L >= 0 && R < s.length() && s.charAt(L) == s.charAt(R)) {
        L--;
        R++;
    }
    return R - L - 1;
}
}

6. Z 字形变换

class Solution {
public:
    string convert(string s, int numRows) 
    {
        if(numRows <= 1)
        {
            return s;            
        }
        string res = "";
        int size = 2 * numRows - 2;
        for(int i = 0;i < numRows;i ++)
        {
            for(int j = i;j < s.size();j +=size)
            {
                res += s[j];
                int temp = j + size - 2 * i;
                if(i != 0 && i != numRows - 1 && temp < s.size())
                {
                    res += s[temp];
                }
            }
        }
        return res;
    }
};
class Solution {
    public String convert(String s, int numRows) {
        if (numRows == 1) return s;

        StringBuilder ret = new StringBuilder();
        int n = s.length();
        int cycleLen = 2 * numRows - 2;

        for (int i = 0; i < numRows; i++) 
        {
            for (int j = 0; j + i < n; j += cycleLen) 
            {
                ret.append(s.charAt(j + i));
                if (i != 0 && i != numRows - 1 && j + cycleLen - i < n)
                    ret.append(s.charAt(j + cycleLen - i));
            }
        }
        return ret.toString();
    }
}

7. 整数反转

class Solution {
public:
    int reverse(int x) 
    {
        long long res = 0;
        while (x) 
        {
            res = 10 * res + x % 10;
            x /= 10;
        }
        return (res > INT_MAX || res < INT_MIN) ? 0 : res;
    }
};
class Solution {
    public int reverse(int x) {        
        long temp=0;
        while(x!=0){
            temp*=10;
            temp+=x%10;
            x/=10;
        }
        if(temp<Integer.MIN_VALUE || temp>Integer.MAX_VALUE)
            return 0;
        return (int)temp;
    }
}

8. 字符串转换整数 (atoi)

class Solution {
public:
    int myAtoi(string str) 
    {
        if (str.empty())
        {
            return 0;
        }
        int sign = 1, base = 0, i = 0, n = str.size();
        while (i < n && str[i] == ' ')
        {
            ++i;
        }
        if (str[i] == '+' || str[i] == '-') 
        {
            sign = (str[i++] == '+') ? 1 : -1;
        }
        while (i < n && str[i] >= '0' && str[i] <= '9') 
        {
            if (base > INT_MAX / 10 || (base == INT_MAX / 10 && str[i] - '0' > 7)) 
            {
                return (sign == 1) ? INT_MAX : INT_MIN;
            }
            base = 10 * base + (str[i++] - '0');
        }
        return base * sign;
    }
};
class Solution {
    public int myAtoi(String str) {
        str = str.trim();
        if (str == null || str.length() == 0)
            return 0;

        char firstChar = str.charAt(0);
        int sign = 1;
        int start = 0;
        long res = 0;
        if (firstChar == '+') {
            sign = 1;
            start++;
        } else if (firstChar == '-') {
            sign = -1;
            start++;
        }

        for (int i = start; i < str.length(); i++) {
            if (!Character.isDigit(str.charAt(i))) {
                return (int) res * sign;
            }
            res = res * 10 + str.charAt(i) - '0';
            if (sign == 1 && res > Integer.MAX_VALUE)
                return Integer.MAX_VALUE;
            if (sign == -1 && res > Integer.MAX_VALUE)
                return Integer.MIN_VALUE;
        }
        return (int) res * sign;
}
}

9. 回文数

bool isPalindrome(int x) 
{
    int reverse = 0;
    int back = x;
    
    if(x == 0)
        return true;
    if(x < 0 || x % 10 == 0)
        return false;
    while(x)
    {
        reverse = reverse * 10 + x % 10;
        x /= 10;
    }
    return back == reverse; 
}
class Solution {
    public boolean isPalindrome(int x) {
        int res = 0;
        int tmp = x;
        if(x < 0)
        {
            return false;
        }
        while(x != 0)
        {
            res = res*10 + x%10;
            x /= 10;
        }
        return res == tmp ? true : false;
    }
}

11. 盛最多水的容器

class Solution {
public:
    int maxArea(vector<int>& height) 
    {
        int water = 0;
        int max_water = 0;
        for(int i = 0;i < height.size();i ++)
        {
            for(int j = i;j < height.size();j ++)
            {
                water = (j - i)*min(height[i],height[j]);
                max_water = max(water,max_water);
            }
        }
        return max_water;
    }
};
class Solution {
    /*暴力法
    public int maxArea(int[] height) {
        int water = 0;
        int max_water = 0;
        for(int i = 0;i < height.length;i ++)
        {
            for(int j = i;j < height.length;j ++)
            {
                water = (j - i) * Math.min(height[i], height[j]);
                max_water = Math.max(water, max_water);
            }
        }
        return max_water;
    }*/
    
    /*双指针法*/
    public int maxArea(int[] height) {
        int maxarea = 0, l = 0, r = height.length - 1;
        while (l < r) {
            maxarea = Math.max(maxarea, Math.min(height[l], height[r]) * (r - l));
            if (height[l] < height[r])
                l++;
            else
                r--;
        }
        return maxarea;
    }
}

13. 罗马数字转整数

int romanToInt(char* s) 
{
    char *input = s;
    int output = 0;
    int i = 0;
    while(i < strlen(input))
    {
        if(input[i] == 'I')
        {
            if(input[i+1] == 'V')
            {
                output += 4;
                i += 2;
            }
            else if (input[i+1] == 'X')
            {
                output += 9;
                i += 2;
            }
            else
            {
                output += 1;
                i += 1;
            }      
        }
        if(input[i] == 'X')
        {
            if(input[i+1] == 'L')
            {
                output += 40;
                i += 2;
            }
            else if (input[i+1] == 'C')
            {
                output += 90;
                i += 2;
            }
            else
            {
                output += 10;
                i += 1;
            }  
        }
        if(input[i] == 'C')
        {
            if(input[i+1] == 'D')
            {
                output += 400;
                i += 2;
            }
            else if (input[i+1] == 'M')
            {
                output += 900;
                i += 2;
            }
            else
            {
                output += 100;
                i += 1;
            }  
        }
        if(input[i] == 'V')
        {
            output += 5;
            i += 1;
        }
        if(input[i] == 'L')
        {
            output += 50;
            i += 1;
        }
        if(input[i] == 'D')
        {
            output += 500;
            i += 1;
        }
        if(input[i] == 'M')
        {
            output += 1000;
            i += 1;
        }
    }
    return output; 
}
class Solution {
    public int romanToInt(String s) {
        int res = 0;
        HashMap<String,Integer> map = new HashMap<String,Integer>();
        map.put("I",  1);
        map.put("IV", 4);
        map.put("V",  5);
        map.put("IX", 9);
        map.put("X",  10);
        map.put("XL", 40);
        map.put("L",  50);
        map.put("XC", 90);
        map.put("C",  100);
        map.put("CD", 400);
        map.put("D",  500);
        map.put("CM", 900);
        map.put("M",  1000);
        
        for(int i = 0;i < s.length();)
        {
            if(i + 1 < s.length() && map.containsKey(s.substring(i, i+2)))
            {
                res += map.get(s.substring(i, i+2));
                i +=2;
            }
            else
            {
                res += map.get(s.substring(i, i+1));
                i ++;
            }
        }
        
        return res;
    }
}

14. 最长公共前缀

class Solution {
public:
    string longestCommonPrefix(vector<string>& strs) 
    {
        if(strs.empty())
        {
            return "";
        }
        string res = "";
        for(int i = 0;i < strs[0].size();i ++)
        {
            char c = strs[0][i];
            for(int j = 1;j < strs.size();j ++)
            {
                if(strs[j][i] != c || i >= strs[i].size())
                {
                    return res;
                }
            }
            res.push_back(c);
        }
        return res;
    }
};

class Solution {
    public String longestCommonPrefix(String[] strs) {
        if(strs.length == 0)
        {
            return "";
        }
        
        String res = strs[0];
        for(int i = 1;i < strs.length;i ++)
        {
            int j = 0;
            for(;j < res.length() && j < strs[i].length();j ++)
            {
                if(res.charAt(j) != strs[i].charAt(j))
                {
                    break;
                }
            }
            res = res.substring(0, j);
        }
        return res;
    }
}

20. 有效的括号

class Solution {
public:
    bool isValid(string s) 
    {
        stack<char> kuohao;
        for(int i = 0;i < s.size();i ++)
        {
            if(s[i] == '(' || s[i] == '[' || s[i] == '{')
            {
                kuohao.push(s[i]);
            }
            else
            {
                if(kuohao.empty())
                {
                    return false;
                }
                if(s[i] == ')' && kuohao.top() != '(')
                {
                    return false;
                }
                if(s[i] == ']' && kuohao.top() != '[')
                {
                    return false;
                }
                if(s[i] == '}' && kuohao.top() != '{')
                {
                    return false;
                }
                kuohao.pop();
            }
        }
        return kuohao.empty();    
    }
};
class Solution {
    public boolean isValid(String s) {
        while(s.contains("()") || s.contains("[]") || s.contains("{}"))
        {
            if(s.contains("()"))
            {
                s = s.replace("()", "");
            }
            if(s.contains("[]"))
            {
                s = s.replace("[]", "");
            }
            if(s.contains("{}"))
            {
                s = s.replace("{}", "");
            }
        }
        return s.isEmpty();
    }
}

21. 合并两个有序链表

class Solution {
public:
    ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) 
    {     
        ListNode *dummy = new ListNode(-1), *cur = dummy;
        while (l1 && l2) {
            if (l1->val < l2->val) {
                cur->next = l1;
                l1 = l1->next;
            } else {
                cur->next = l2;
                l2 = l2->next;
            }
            cur = cur->next;
        }
        cur->next = l1 ? l1 : l2;
        return dummy->next; 
    }
};
/*递归*/
class Solution {
    public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
        if(l1 == null)
        {
            return l2;
        }
        if(l2 == null)
        {
            return l1;
        }
        
        if(l1.val < l2.val)
        {
            l1.next = mergeTwoLists(l1.next, l2);
            return l1;
        }
        else
        {
            l2.next = mergeTwoLists(l1, l2.next);
            return l2;
        }
    }
}

26. 删除排序数组中的重复项

class Solution {
public:
    int removeDuplicates(vector<int>& nums) 
    {
        int pre = 0;
        if(nums.empty())
        {
            return 0;
        }
        for(int i = 0;i < nums.size() - 1;i ++)
        {
            if (nums[i] != nums[i + 1])
            {
                nums[++pre] = nums[i + 1];
            }
        }
        return pre + 1;
    }
};
class Solution {
    public int removeDuplicates(int[] nums) {
        int count = 0;
        for(int i = 0;i < nums.length - 1;i ++)
        {
            if(nums[i] != nums[i + 1])
            {
                /*不需要考虑数组中超出新长度后面的元素*/
                nums[++count] = nums[i + 1];
            }
        }
        return count + 1;
    }
}

27 移除元素

class Solution {
public:
    int removeElement(vector<int>& nums, int val) 
    {
        int count = 0;
        for(int i = 0;i < nums.size();i ++)
        {
            if(nums[i] != val)
            {
                nums[count++] = nums[i];
            }
        }
        return count;
    }
};
class Solution {
    public int removeElement(int[] nums, int val) {
        int count = 0;
        for(int i = 0;i < nums.length;i ++)
        {
            if(nums[i] != val)
            {
                nums[count++] = nums[i];
            }
        }
        return count;
    }
}

28. 实现 strStr()

class Solution {
public:
    int strStr(string haystack, string needle) 
    {
        int i,j = 0;
        if(needle.empty())
        {
            return 0;
        }
        if(haystack.size() < needle.size())
        {
            return -1;
        }
        for(i = 0;i < haystack.size();i ++)
        {
            for(j = 0;j < needle.size();j ++)
            {
                if(haystack[i + j] != needle[j])
                {
                    break;
                }
            }
            if(j == needle.size())
            {
                return i;
            }
        }
        return -1;
    }
};
class Solution {
    public int strStr(String haystack, String needle) {
        int res = -1;
        int len = needle.length();
        int lenhay = haystack.length();
        if ( lenhay < len )
            return -1;
        int star = 0 ;
        int end = len-1;
        while (end < lenhay){
             if (haystack.substring(star,end+1).equals(needle)){
                 return star;
             }
            end++;
            star++;
        }
        return -1;
    }
}

35. 搜索插入位置

class Solution {
public:
    int searchInsert(vector<int>& nums, int target) 
    {
        if(target < nums[0])
        {
            return 0;
        }
        if(target > nums[nums.size() - 1])
        {
            return nums.size();
        }
        for(int i = 0;i < nums.size();i ++)
        {
            if(target - nums[i] == 0)
            {
                return i;
            }
            else if(target - nums[i] > 0 && target - nums[i + 1] < 0)
            {
                return i + 1;
            }
        }
    }
};
class Solution {
    public int searchInsert(int[] nums, int target) {
        int left = 0;
        int right = nums.length;
        while(left < right)
        {
            int mid = (left + right) / 2;
            if(target > nums[mid])
            {
                left = mid + 1;
            }
            else if(target < nums[mid])
            {
                right = mid;
            }
            else
            {
                return mid;
            }
        }
        return right;

38. 报数

class Solution {
public:
    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;
    }
};
class Solution {
    public String countAndSay(int n) {
        if (n <= 0) {
            return "";
        }
        String[] seq = new String[n];
        seq[0] = "1";
        for (int i = 1; i < n; i++) {
            seq[i] = convert(seq[i - 1]);
        }
        return seq[n - 1];
    }

    public String convert(String str) {
        StringBuilder ans = new StringBuilder();
        int count = 1;
        for (int i = 0; i < str.length(); i++) {
            // 这一部分是"count", 记录连续出现x个y
            if (i < str.length() - 1 && str.charAt(i) == str.charAt(i + 1)) {
                count++;
            } else {
            // 这一部分是"say",将上面"count"的结果"xy"作为下一个数的一部分(若上面记录到2个1,就拼接"21")
                ans.append(count).append(str.charAt(i));
                count = 1;
            }
        }
        return new String(ans);
    }
}

猜你喜欢

转载自blog.csdn.net/sinat_33408502/article/details/100103751