Leetcode Proble 汇总四

第一题:

Permutations

分析:全排列问题,DFS即可。

代码:

vector<int> visit;
int size;
vector<vector<int>> ans;
vector<int> add;
void dfs(int pos, vector<int> &num)
{
	int i;
	if (pos == size)
	{
		ans.push_back(add);
		return ;
	}
	for (i = 0; i < size; i++)
	{
		if (visit[i] == 0)
		{
			visit[i] = 1;
			add.push_back(num[i]);
			dfs(pos+1, num);
			visit[i] = 0;
			add.pop_back();
		}
	}
}
class Solution 
{
public:
    vector<vector<int> > permute(vector<int> &num) 
	{
        int i;
		ans.clear();
		add.clear();
		size = num.size();
		if (size == 0) return ans;
		for (i = 0; i < size; i++) visit.push_back(0);
		dfs(0, num);

		return ans;
    }
};

第二题:

Length of Last Word

分析:水题。

代码:

class Solution 
{
public:
    int lengthOfLastWord(const char *s) 
	{
		int i, ans = 0, l1, flag;
		l1 = strlen(s);
		i = l1-1;
		while (s[i] == ' ') i--;
		for ( ; i >= 0; i--)
		{
			if (s[i] != ' ') ans += 1;
			else break;
		}
		return ans;
    }
};

第三题:

Linked List Cycle

分析:设置两个指针,一个跑得快,一个跑得慢。

代码:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution 
{
public:
    bool hasCycle(ListNode *head) 
    {
        ListNode* slow = head;
        ListNode* fast = head;
        while (fast != NULL && fast->next != NULL)
        {
            slow = slow->next;
            fast = fast->next->next;
            if (slow == fast) return true;
        }
        return false;
    }
};

第四题:

Maximal Rectangle

分析:和以前

Largest Rectangle in Histogram

题目处理方法一样,所以复杂度是O(mn),对每一行进行处理。

代码:

int work(vector<int> &height)
{
	stack<int> s;
	int n = height.size();
	int max_are = 0;
	int tp, are_with_top;

	int i = 0;
	while (i < n)
	{
		if (s.empty() || height[s.top()] <= height[i])
			s.push(i++);
		else
		{
			tp = s.top();
			s.pop();
			are_with_top = height[tp] * (s.empty() ? i : i-s.top()-1);
			if (max_are < are_with_top) max_are = are_with_top;
		}
	}
	while (s.empty() == false)
	{
		tp = s.top();
		s.pop();
		are_with_top = height[tp] * (s.empty() ? i : i-s.top()-1);
		if (max_are < are_with_top) max_are = are_with_top;
	}
	return max_are;
}

class Solution 
{
public:
    int maximalRectangle(vector<vector<char> > &matrix) 
    {
		int size1, size2, i, j;
		vector<vector<int>> dp;
		vector<int> add;
		add.clear();
		dp.clear();
		size1 = matrix.size();
		if (size1 == 0) return 0;
		size2 = matrix[0].size();
		for (i = 0; i < size1; i++)
		{
			add.clear();
			for (j = 0; j < size2; j++)
				add.push_back(0);
			dp.push_back(add);
		}
		for (i = 0; i < size2; i++) dp[0][i] = matrix[0][i] == '1' ? 1 : 0;
		for (i = 1; i < size1; i++)
		{
			for (j = 0; j < size2; j++)
			{
				if (matrix[i][j] == '1') dp[i][j] = dp[i-1][j]+1;
				else dp[i][j] = 0;
			}
		}
		vector<int> height;
		int ans = 0, ret;
		for (i = 0; i < size1; i++)
		{
			height.clear();
			for (j = 0; j < size2; j++) height.push_back(dp[i][j]);
			ret = work(height);
			if (ret > ans) ans = ret;
		}
		
		return ans;
    }
};

第五题:

Linked List Cycle II

分析:如 Linked List Cycle I

代码:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution 
{
public:
    ListNode *detectCycle(ListNode *head) 
    {
        ListNode* slow = head;
        ListNode* fast = head;
        while (fast != NULL && fast->next != NULL)
        {
            slow = slow->next;
            fast = fast->next->next;
            if (slow == fast)
            {
                slow = head;
                while (slow != fast)
                {
                    slow = slow->next;
                    fast = fast->next;
                }
                return slow;
            }
        }
        return NULL;
    }
};;

第六题:

Longest Common Prefix


分析:一开始想错了,其实比较简单吧。

代码:

class Solution 
{  
public:  
    string longestCommonPrefix(vector<string> &strs) 
    {  
        string result;  
        int len = strs.size();  
        int i,j;  
        if (len == 0)return "";  
        for (j = 0; ; ++j)  
        {  
            for (i = 0;i < len; ++i)  
                if (j >= strs[i].length() || strs[i][j] != strs[0][j]) break;  
            if (i < len) break;  
            result += strs[0][j];  
        } 
        return result;          
    }  
}; 

第七题:

Binary Tree Maximum Path Sum


分析:一开始读错题了,看成必须是从叶子开始,到叶子结束。应该是从任意一个节点开始就可以==。好囧Orz。。。 动态规划。

代码:

int MAX(int a, int b) { return a > b ? a : b;}
int maxnum;
void dfs(TreeNode *root)
{
	int a, b;
	if (root == NULL) return;
	dfs(root->left);
	dfs(root->right);

	if (root->left != NULL) a = root->left->val;
	else a = 0;
	if (root->right != NULL) b = root->right->val;
	else b = 0;
	if (root->val + a + b > maxnum) maxnum = root->val + a + b;
	if (root->val > maxnum) maxnum = root->val;
	if (a > 0 || b > 0) root->val += MAX(a, b);
	if (root->val > maxnum) maxnum = root->val;
}

class Solution 
{
public:
    int maxPathSum(TreeNode *root) 
	{
		maxnum = -100000000;
        dfs(root);
		return maxnum;
    }
};

第八题:

Best Time to Buy and Sell Stock

分析:逗比了。理解错题意了。只买卖一次 =-=。 O(n)的复杂度。

代码:

int dp[101000];
class Solution
{
public:
    int maxProfit(vector<int> &prices) 
    {
		int i, j, size, maxnum, ans = 0;
        memset(dp, 0, sizeof(dp));
		size = prices.size();
		if (size == 0) return 0;
		maxnum = size-1;
		dp[size-1] = prices[size-1];
		for (i = size-2; i >= 0; i--)
		{
			if (prices[i] > prices[maxnum]) maxnum = i;
			dp[i] = maxnum;
		}
		maxnum = 0;
		for (i = 0; i < size-1; i++)
		{
			if (prices[i] >= prices[i+1] && i+1 < size) continue;
			ans = prices[dp[i]]-prices[i];
			if (ans > maxnum) maxnum = ans;
		}
		return maxnum;
    }
};

第九题:

Best Time to Buy and Sell Stock II

分析:贪心。

代码:

class Solution 
{
public:
    int maxProfit(vector<int> &prices) 
    {
        int ans = 0, size = prices.size(), i;
        for (i = 1; i < size; i++)
            ans += prices[i]-prices[i-1] > 0 ? prices[i]-prices[i-1] : 0;
        return ans;
    }
};

第十题:

Best Time to Buy and Sell Stock III

分析:动态规划,可以参考上面第八题,开两个数组,一个用于正向DP,一个用于逆向DP,然后扫描一遍就OK了。O(n)复杂度。

代码:

int dp1[50000];
int dp2[50000];
class Solution 
{
public:
    int maxProfit(vector<int> &prices) 
    {
		int i, size;
		int minnum, maxnum, bestans;
		minnum = 100000000, maxnum = 0, bestans = 0;
		size = prices.size();
		if (size <= 1) return 0;
		for (i = 0; i < size; i++)
		{
			if (prices[i] < minnum)
			{
				minnum = prices[i];
				maxnum = 0;
			}
			if (prices[i] > maxnum)
			{
				maxnum = prices[i];
				if (maxnum - minnum > bestans) bestans = maxnum-minnum;
			}
			dp1[i] = bestans;
		}
		maxnum = 0, minnum = 100000000, bestans = 0;
		for (i = size-1; i >= 0; i--)
		{
			if (prices[i] > maxnum)
			{
				maxnum = prices[i];
				minnum = 100000000;
			}
			if (prices[i] < minnum)
			{
				minnum = prices[i];
				if (maxnum - minnum > bestans) bestans = maxnum - minnum;
			}
			dp2[i] = bestans;
		}
		bestans = 0;
		for (i = 0; i < size; i++)
		{
			if (dp1[i] + dp2[i] > bestans) bestans = dp1[i]+dp2[i];
		}
		
		return bestans;
    }
};

第十一题:

Linked List Cycle

分析:两个指针,一个一次走一步,另一个一次走两步。如果有环的话,肯定能够相遇的。没有的话。。。

代码:

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution:
    # @param head, a ListNode
    # @return a boolean
    def hasCycle(self, head):
        a = head
        b = head
        if head == None:
            return False
        while True:
            if a.next == None or a.next.next == None:
                return False
            a = a.next.next
            b = b.next
            if a == b:
                return True

第十二题:

Search in Rotated Sorted Array

分析:数组是排序然后旋转的,所以利用二分可以实现O(logn)

如果A[mid] > A[left] 那么mid左边一定是有序的,同理判断右。如果无序的话,那么无非就是先升后降,或者先降后升,然后判断一下即可。

class Solution:
    # @param A, a list of integers
    # @param target, an integer to be searched
    # @return an integer
    @staticmethod
    def gao(A, left, right, target):
        while left <= right:
            mid = (left + right) // 2
            if target == A[mid]: return mid
            if A[mid] > A[left] and target >= A[left] and target <= A[mid]:
                right = mid - 1     
            elif A[mid] < A[right] and target >= A[mid] and target <= A[right]:
                left = mid + 1
            elif (A[mid] > target or A[left] <= target) and A[mid] < A[left]:
                right = mid-1
            else: left = mid + 1
        return -1
    def search(self, A, target):
        return Solution.gao(A, 0, len(A)-1, target)

第十三题:

Container With Most Water

分析:有n个高度不同的木板,他们之间的相邻距离为1,让你求用这些木板最多能够盛多少水。

贪心问题。 两个指针,一个指向头pi,一个指向尾pj,如果height[pi] < height[pj], 可以分析,这已经是利用pi为边界来盛水的容量极限了。

所以就将pi指针向右移。如此即可。

class Solution:
    # @return an integer
    def maxArea(self, height):
        ans = 0
        width, i, j = [len(height) - 1, len(height) - 1, 0]
        while j < i:
            ans = max(min(height[i], height[j]) * width , ans)
            width -= 1
            if height[i] > height[j]:
                j += 1
            else:
                i -= 1
        return ans

第十四题:

Unique Binary Search Trees

分析:直接套公式 (2n)!/(n+1)!/n!,结果要求是int,用地板除搞一下。不过貌似不用地板除也没问题。。。

代码:

class Solution:
    # @return an integer
    @staticmethod
    def gao(a, b):
        ans = 1
        while a <= b:
            ans = ans * a
            a += 1
        return ans
    def numTrees(self, n):
        if n < 2: return n
        ans = Solution.gao(n+2, 2*n) // Solution.gao(1, n) 
        return ans

第十五题:

Insertion Sort List

分析:链表的基本操作,硬伤。。。

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution:
    # @param head, a ListNode
    # @return a ListNode
    def insertionSortList(self, head):
        if head == None: return None
        go = ListNode(0)
        ans = ListNode(0)
        ans.next = go
        go.__init__(head.val)
        last = head.val
        it = head.next
        while it != None:
            aa = ans.next
            pre = ans
            if it.val < last:
                while aa != None:
                    if aa.val > it.val:
                        break
                    pre = aa
                    aa = aa.next
                pre.next = it
                it = it.next
                pre.next.next = aa
            else:
                last = it.val
                go.next = it
                it = it.next
                go.next.next = None
                go = go.next
        return ans.next


第十六题:

First Missing Positive

分析:

交换数组元素,使得数组中第i位存放数值(i+1)。最后遍历数组,寻找第一个不符合此要求的元素,返回其下标。整个过程需要遍历两次数组,复杂度为O(n)

PS: 写过一次,但是那个是错误的=。=用了非常数大小的内存。。。所以以前那个不对。

代码:

class Solution:
    # @param A, a list of integers
    # @return an integer
    def firstMissingPositive(self, A):
        i = 0
        while i < len(A):
            if A[i] != (i+1) and A[i] >= 1 and A[i] <= len(A) and A[A[i]-1] != A[i]:
                temp = A[i]
                A[i] = A[A[i]-1]
                A[temp-1] = temp
            else:
                i += 1
        i = 0
        for i in range(len(A)):
            if A[i] != i+1:
                return i+1
        return len(A)+1

第十七题:

Sum Root to Leaf Numbers

分析: DFS一下即可。一开始忘记每次都要初始化ans了。。然后WA了一发。

代码:

# Definition for a  binary tree node
class TreeNode:
    def __init__(self, x):
        self.val = x
        self.left = None
        self.right = None

class Solution:
    # @param root, a tree node
    # @return an integer
    ans = 0
    @staticmethod
    def dfs(root, cc):
        cc = cc + root.val
        if root.left == None and root.right == None:
            Solution.ans = Solution.ans + cc
            return
        if root.left != None:
            Solution.dfs(root.left, 10*cc)
        if root.right != None:
            Solution.dfs(root.right, 10*cc)
    def sumNumbers(self, root):
        if root == None:
            return 0
        Solution.ans = 0
        Solution.dfs(root, 0)
        return Solution.ans

第十八题:

Set Matrix Zeroes

分析:要求把matrix中的0所在的行以及列全部元素置为0,并且原地操作。只能使用常数内存。

我们可以用matrix 的第0行以及第0列来表示matrix中的0的位置。

比如matrix[4][3]处为0,那么matrix[4][0]即为0,matrix[0][3]也为0.

这样有另一个问题,即第0行以及第0列的存在的0如何表示,我们用flag1以及flag2两个标记。来分别

表示第0行存在0,或者第0列存在0.然后扫描一下matrix即可。

class Solution:
    # @param matrix, a list of lists of integers
    # RETURN NOTHING, MODIFY matrix IN PLACE.
    def setZeroes(self, matrix):
        m, n = [len(matrix), len(matrix[0])]
        flag1, flag2 = [0, 0]
        for i in range(m):
            for j in range(n):                         
                if matrix[i][j] == 0:
                    if i == 0 and j == 0:
                        flag1 = 1
                        flag2 = 1
                    elif i == 0: 
                        flag1 = 1
                        matrix[0][j] = 0
                    elif j == 0: 
                        flag2 = 1
                        matrix[i][0]
                    else:
                        matrix[i][0] = 0
                        matrix[0][j] = 0
        i = 1
        while i < n:
            if matrix[0][i] == 0:
                for j in range(m):
                    matrix[j][i] = 0
            i = i + 1
        i = 0
        while i < m:
            if matrix[i][0] == 0:
                for j in range(n):
                    matrix[i][j] = 0
            i = i + 1
        if flag1 == 1:
            for j in range(n):
                matrix[0][j] = 0
        if flag2 == 1:
            for j in range(m):
                matrix[j][0] = 0

第十九题:

Restore IP Addresses

分析:一字符串判断是否为合法IP地址,若合法,就转化。

注意的问题:

①、 如果串长度大于12,肯定不是。

②、a.b.c.d 每个数字的取值范围是 0~255

③、 0.01.0.0 这不是合法的,因为在第二个是01即若数字的长度大于1且第一位为0,,则不合法。

代码:

class Solution:
    # @param s, a string
    # @return a list of strings
    @staticmethod
    def judge(i, j, k, s):       
        a, b, c, d = [0, 0, 0, 0]
        for m in range(i+1):
            a = a*10 + int(s[m])
            if s[0] == '0' and i > 0: a = 299
        for m in range(i+1, j+1): 
            b = b*10 + int(s[m])
            if s[i+1] == '0' and (j-i) > 1: b = 299
        for m in range(j+1, k+1):
            c = c*10 + int(s[m])
            if s[j+1] == '0' and (k-j) > 1: c = 299
        for m in range(k+1, len(s)):
            d = d*10 + int(s[m])
            if s[k+1] == '0' and (len(s)-k-1) > 1: d = 299#
        if a >= 0 and a <= 255 and b >= 0 and b <= 255 and c >= 0 and c <= 255 and d >= 0 and d <= 255:
            ret = str(a) + '.' + str(b) + '.' + str(c) + '.' + str(d)
            return ret
        return '-'
    def restoreIpAddresses(self, s):
        ans = []
        if len(s) > 12: return ans
        for i in range(len(s)-3):
            for j in range(i+1, len(s)-2):
                for k in range(j+1, len(s)-1):
                    ret = Solution.judge(i, j, k, s)
                    if ret != '-':
                        ans.append(ret)
        return ans

第二十题:

Search Insert Position

分析:二分。如果没有则返回left的值,此时left即为大于target 的第一个数的index

代码:

class Solution:
    # @param A, a list of integers
    # @param target, an integer to be inserted
    # @return integer
    @staticmethod
    def binary_search(A, target):
        left, right = [0, len(A)-1]
        while left <= right:
            mid = (left + right) // 2
            if A[mid] == target:
                return mid
            elif A[mid] <  target:
                left = mid + 1 
            else:
                right = mid - 1
        return left
    def searchInsert(self, A, target):
        return Solution.binary_search(A, target)


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值