一天三题LeetCode(C++&JAVA)-4~6

转载请注明出处:

http://blog.csdn.net/miaoyunzexiaobao

4.     Median ofTwo Numbers

https://leetcode.com/problems/median-of-two-sorted-arrays/

给定两个有序数组A(长度为m)和B(长度为n),找到两个数组的中位数。若两个数组长度和为偶数,则返回中间两个数的平均值。例:A={1,5,14},B={3,7,30},则返回(5+7)/2=6.A={1,5,14},B={3,7},返回5。要求时间复杂度为log(m+n)

思路:

参考链接:http://blog.csdn.net/yutianzuijin/article/details/11499917/

简单的方法是将两个有序数组合并成一个,然后返回该数组的中间值。但在LeetCode中测试时会出现超时的问题。

这里将问题转化为更一般的情况:求两个有序数组合并起来,按序排列后的第k个值。然后利用A和B是有序数组的特性,首先假设数组A和B的元素个数都大于k/2,我们比较A[k/2-1]和B[k/2-1]两个元素,这两个元素分别表示A的第k/2小的元素和B的第k/2小的元素。这两个元素比较共有三种情况:>、<和=。

1.   A[k/2-1]<B[k/2-1],这表示A[0]到A[k/2-1]的元素都在A和B合并之后的前k小的元素中。换句话说,A[k/2-1]不可能大于两数组合并之后的第k小值,所以我们可以将其抛弃。

2.   当A[k/2-1]>B[k/2-1]时存在类似的结论。

3.   当A[k/2-1]=B[k/2-1]时,我们已经找到了第k小的数,也即这个相等的元素,我们将其记为m。由于在A和B中分别有k/2-1个元素小于m,所以m即是第k小的数。

这里如果k为奇数,则m不是中位数。在实际代码中是先求k/2,然后利用k-k/2获得另一个数

通过上面的分析,我们即可以采用递归的方式实现寻找第k小的数。此外我们还需要考虑几个边界条件:

  • 如果A或者B为空,则直接返回B[k-1]或者A[k-1];
  • 如果k为1,我们只需要返回A[0]和B[0]中的较小值;
  • 如果A[k/2-1]=B[k/2-1],返回其中一个;

C++:

int findKth(int A[],int B[],int k,int m,int n){
	if(m>n)
		return findKth(B,A,k,n,m);
	if(m == 0)
		return B[k-1];
	if(k == 1)
		return (A[k-1]<B[k-1]?A[k-1]:B[k-1]);

	int pa = (k/2 < m ? k/2 : m);
	int pb = k - pa;

	if(A[pa - 1] < B[pb - 1])
		return findKth(A+pa,B,k-pa,m-pa,n);
	else if(A[pa - 1] > B[pb - 1])
		return findKth(A,B+pb,k-pb,m,n-pb);
	else
		return A[pa - 1];
}
double findMedianSortedArrays(int A[], int m, int B[], int n)
{
	int total = m + n;
	if(total % 2 !=0)
		return (double)(findKth(A,B,total/2+1,m,n));
	else
		return (findKth(A,B,total/2,m,n)+findKth(A,B,total/2+1,m,n))/2.0 ;

}

JAVA:

public static int findKth(int A[], int B[], int k) {
		int aLen = A.length;
		int bLen = B.length;

		if (aLen > bLen)
			return findKth(B, A, k);
		if (aLen == 0)
			return B[k - 1];
		if (k == 1)
			return Math.min(A[0], B[0]);

		int pa = Math.min(k / 2, aLen);
		int pb = k - pa;

		if (A[pa - 1] < B[pb - 1])
			return findKth(Arrays.copyOfRange(A, pa, aLen), B, k - pa);
		else
			return findKth(A, Arrays.copyOfRange(B, pb, bLen), k - pb);
	}

	public static double findMedianSortedArrays(int A[], int B[]) {
		int m = A.length;
		int n = B.length;
		int mid = (m + n) / 2;

		if ((m + n) % 2 == 0)
			return (double) (findKth(A, B, mid) + findKth(A, B, mid + 1)) / 2.0;
		else
			return (double) findKth(A, B, mid + 1);
	}

5.      LongestPalindromic Substring

https://leetcode.com/problems/longest-palindromic-substring/

给定一个字符串,求出其最长回文子串。

思路:

参考链接:

http://blog.csdn.net/zhouworld16/article/details/16842467

解法1:逆转该字符串,则问题转换为求两个字符串的最长公共子字符串

解法2:动态规划。用booldp[i][j]表示子串从第i个字符到第j个字符是否为回文子串。易知:

初始条件可设置长度为1和为2的dp。即可确定dp[i][i]=
true,dp[i][i+1] = (s[i] == s[i+1])

判断条件为:dp[i ][ j ] = dp[ i + 1][ j - 1] && s[ i ] == s[ j ]。

解法3:中心扩展法。利用回文是中心对称的特性,从下标i出发,用两个指针分别向i的左右两边移动,判断是否相等。需要注意的是回文有奇偶数之分。如abc和abba两种类型。

C++:

static string expandAroundCenter(string s, int c1, int c2) {
		int l = c1, r = c2;
		int n = s.length();
		while (l >= 0 && r <= n-1 && s[l] == s[r]) {
			l--;
			r++;
		}
		return s.substr(l+1, r-l-1);
	}

	static string longestPalindrome(string s) {
		int n = s.length();
		if (n == 0) return "";
		string longest = s.substr(0, 1);  // a single char itself is a palindrome
		for (int i = 0; i < n-1; i++) {
			string p1 = expandAroundCenter(s, i, i);
			if (p1.length() > longest.length())
				longest = p1;

			string p2 = expandAroundCenter(s, i, i+1);
			if (p2.length() > longest.length())
				longest = p2;
		}
		return longest;
	}

JAVA:

public static String longestPalindrome(String s) {
		if (s.isEmpty()) {
			return null;
		}
		if (s.length() == 1) {
			return s;
		}
		String longest = s.substring(0, 1);
		for (int i = 0; i < s.length(); i++) {
			String tmp = helper(s, i, i);
			if (tmp.length() > longest.length()) {
				longest = tmp;
			}
			tmp = helper(s, i, i + 1);
			if (tmp.length() > longest.length()) {
				longest = tmp;
			}
		}

		return longest;
	}
	public static String helper(String s, int begin, int end) {
		while (begin >= 0 && end <= s.length() - 1
				&& s.charAt(begin) == s.charAt(end)) {
			begin--;
			end++;
		}
		return s.substring(begin + 1, end);
	}

6.      ZigZagConversion

https://leetcode.com/problems/zigzag-conversion/

把一个字符串用ZigZag的形式表示并打印出来。比如"PAYPALISHIRING"按照ZIgZag的形式为:

P   A   H   N
A P L S I I G
Y   I   R

打印出来即为:"PAHNAPLSIIGYIR"

思路:

见参考链接:

http://blog.csdn.net/zhouworld16/article/details/14121477

C++:

string convert(string s, int nRows) {
          if (nRows <= 1 || s.length() == 0)
           return s;  

        string res = "";
        int len = s.length();
        for (int i = 0; i < len && i < nRows; ++i)
        {
            int indx = i;
            res += s[indx];  

            for (int k = 1; indx < len; ++k)
            {
                //第一行或最后一行,使用公式1:
                if (i == 0 || i == nRows - 1)
                {
                    indx += 2 * nRows - 2;
                }
                //中间行,判断奇偶,使用公式2或3
                else
                {
                    if (k & 0x1)  //奇数位
                        indx += 2 * (nRows - 1 - i);
                    else indx += 2 * i;
                }
                //判断indx合法性
                if (indx < len)
                {
                    res += s[indx];
                }
            }
        }
        return res;
    }

JAVA:

public static String convert(String s, int nRows) {
		if (s == null || s.length() <= nRows || nRows <= 1)
			return s;
		StringBuffer sb = new StringBuffer();
		for (int i = 0; i < s.length(); i += 2 * (nRows - 1))
			sb.append(s.charAt(i));

		for (int i = 1; i < nRows - 1; ++i)
			for (int j = i; j < s.length(); j += 2 * (nRows - 1)) {
				sb.append(s.charAt(j));
				if (j + 2 * (nRows - i - 1) < s.length())
					sb.append(s.charAt(j + 2 * (nRows - i - 1)));
			}

		for (int i = nRows - 1; i < s.length(); i += 2 * (nRows - 1))
			sb.append(s.charAt(i));

		return sb.toString();
	}
时间: 2024-10-12 22:29:30

一天三题LeetCode(C++&JAVA)-4~6的相关文章

一天三题LeetCode(C++&amp;JAVA)-1~3

转载请注明出处: http://blog.csdn.net/miaoyunzexiaobao 1.      Two Sum https://leetcode.com/problems/two-sum/ 给定一个数组,在其中找两个数,使两个数之和为给定的target.返回这两个数在数组中的位置.两个数字的位置分别用index1和index2表示,要求index1<index2.例: Input: numbers={2, 7, 11, 15}, target=9 Output: index1=1,

LeetCode 第三题,Longest Substring Without Repeating Characters

题目: Given a string, find the length of the longest substring without repeating characters. For example, the longest substring without repeating letters for "abcabcbb" is "abc", which the length is 3. For "bbbbb" the longest s

Leetcode第三题_Longest Substring Without Repeating Characters

Longest Substring Without Repeating Characters Total Given a string, find the length of the longest substring without repeating characters. For example, the longest substring without repeating letters for "abcabcbb" is "abc", which the

2016/1/12 第一题 输出 i 出现次数 第二题 用for循环和if条件句去除字符串中空格 第三题不用endwith 实现尾端字符查询

1 import java.util.Scanner; 2 3 4 public class Number { 5 6 private static Object i; 7 8 /* 9 *第一题 mingrikejijavabu中字符“i” 出现了几次,并将结果输出*/ 10 public static void main(String[] args) { 11 12 String r ="imingrikejijavabi"; 13 14 15 //第一种 截取 16 int a=

Java-集合-第三题 有如下Student 对象, private String name; private int age; private int score; private String classNum; 其中,classNum 表示学生的班号,例如“class05”。 有如下List List list = new ArrayList(); l

第三题 有如下Student 对象, private String name; private int age; private int score; private String classNum; 其中,classNum 表示学生的班号,例如“class05”. 有如下List List list = new ArrayList(); list.add(new Student(“Tom”, 18, 100, “class05”)); list.add(new Student(“Jerry”,

2014百度之星资格赛第三题

Xor Sum Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 132768/132768 K (Java/Others) Total Submission(s): 7837    Accepted Submission(s): 3350 Problem Description Zeus 和 Prometheus 做了一个游戏,Prometheus 给 Zeus 一个集合,集合中包含了N个正整数,随后 Prometheus 将向 Z

第三题作业

第一题: import java.lang.Integer; import java.util.Arrays; class ArrDemo{     public static void main(String[] args){         int[] arr = new int[]{1,20,60,90,4};         //int[] arr = new int[5];//问题2.这个值并没有在错误判断里面,怎么判断?         System.out.println(Arra

MSC阿里比赛第三题详解

第三题的分析过程 图/文 听鬼哥说故事 这道题想起来上次阿里的比赛的ali400.apk,虽然没参加,不过看到过网上的几篇分析文章. 第三题主要是壳子方面的问题,脱壳,再分析看看核心代码在java层还是so层即可. 文章写的详细了点,可以留给初学者参考使用. 详细还是查看文档吧,非常详细的调试过程和思路: 链接:http://pan.baidu.com/s/1bnpkWzl 密码:roii

Linked List Cycle leetcode II java (寻找链表环的入口)

题目: Given a linked list, return the node where the cycle begins. If there is no cycle, return null. Follow up: Can you solve it without using extra space? 题解: 这个连同I都是很经典的题啦,刷CC150时候就折磨了半天. 其实就推几个递推公式就好..首先看图(图引用自CC150): 从链表起始处到环入口长度为:a,从环入口到Faster和Sl