leetcode刷题例程(1)

7 篇文章 0 订阅

Isomorphic Strings相同结构的字符串

Given two strings s and t, determine if they are isomorphic.

Two strings are isomorphic if the characters in s can be replaced to get t.

All occurrences of a character must be replaced with another character while preserving the order of characters. No two characters may map to the same character but a character may map to itself.

For example,
Given "egg""add", return true.

Given "foo""bar", return false.

Given "paper""title", return true.

翻译:给定两个字符串s和t,判断是否结构相同。两个字符串相同,则s中的字母可以经过替换得到t。

字符串中的每一个字母的出现都必须被其对应字母替换,同时要保证顺序不变。两个字母不可以映射到同一个字母,但是一个字母各异映射它本身。

思路:使用HashMap的想法,将两个字符串替换成数字表示,出现过的字母按照前一个出现的数字替换,这样可以判断两个结构是否相同。例如

egg和add,e第一次出现,e->0,g第一次出现,g->1,g第二次出现,g->1,则字符串变成011.

add,a第一次出现,a->0,d第一次出现,d->1,d第二次出现,g->1,则字符串变成011.

所以两者结构相同。

代码:

public class Solution {
    public boolean isIsomorphic(String s, String t) {
	        if(s == null || t == null)
	        	return false;
	        if(s.length() != t.length())
	        	return false;
	        int a[] = new int[128];
	        int b[] = new int[128];
	        for(int i = 0; i < a.length; i++)
	        {
	        	a[i] = -1;
	        	b[i] = -1;
	        }
	        int temp1 = 0;
	        int temp2 = 0;
	        StringBuilder sTemp = new StringBuilder();
	        StringBuilder tTemp = new StringBuilder();
	        for(int i = 0; i < s.length(); i++)
	        {
	        	temp1 = s.charAt(i);
	        	temp2 = t.charAt(i);
	        	if(a[temp1] < 0)
	        	{
	        		a[temp1] = i;
	        	}
        		sTemp.append(a[temp1]);
        		if(b[temp2] < 0)
	        	{
	        		b[temp2] = i;
	        	}
        		tTemp.append(b[temp2]);
	        }
	        if(sTemp.toString().equals(tTemp.toString()))
	        	return true;
			return false;
	    }
}

Decode Ways计算有多少种译码情况

A message containing letters from A-Z is being encoded to numbers using the following mapping:

'A' -> 1
'B' -> 2
...
'Z' -> 26

Given an encoded message containing digits, determine the total number of ways to decode it.

For example,
Given encoded message "12", it could be decoded as "AB" (1 2) or "L" (12).

The number of ways decoding "12" is 2.

翻译:一个消息里原本包含从A到Z,使用如下映射关系,被编码为数字

给定一个编码消息包含数字0-9,计算总共有多少种译码情况。

例如:“12”可以被译码为“AB”或“L”

解法:其实一眼下去我想利用递归的想法去解决这个问题,不过觉得不是最好的解决方法,于是乎就想到了一个动态规划的方法,利用“1234”来解释一下这个想法,首先给一个length的一维数组,

对于第一个数字,只有一种情况,就是A;

对于第二个数字,考虑到只单独用2,则是B,如果考虑两个数字结合,那就要结合前一个数,12就变成L,那就有两种情况;

对于第三个数字,和上面想法一样,如果只考虑3,则情况和第二种一样两种,加上结合前一个数的情况,就要加上第一个数那的情况数,则为三种情况;

对于第四个数字,因为和前面的数字结合没有映射结果,所以只考虑单个数字的映射,那么情况和第三个数字的情况一样,三种。

动态规划的式子是:res[i] = res[i-1]+res[i-2]{ 10<s.charAt(i)+s.charAt(i-1) - 2*'0'<27 }

public int numDecodings(String s) {
			if(s == null || s.length() == 0)
				return 0;
			if(s.charAt(0) == '0')
				return 0;
			if(s.length() == 1 && s.contains("0"))
				return 0;
			if(s.length() == 1)
				return 1;
			char[] array = s.toCharArray();
			int res[] = new int[array.length];
			int temp = 0,preTemp = 0,toal = 0;
			res[0] = 1;
			for(int i = 1; i < s.length(); i++)
			{
				temp = array[i] - '1' + 1;
				preTemp = array[i - 1] - '1' + 1;
				toal = preTemp * 10 + temp;
				if(temp > 0)
					res[i] += res[i - 1];
				if(i > 1 && toal >= 10 && toal <= 26)
					res[i] += res[i - 2];
				else if(toal >= 10 && toal <= 26)
					res[1]++;
			}
			return res[res.length - 1];
	    }


Palindrome Partitioning(回文串分隔)

Given a string s, partition s such that every substring of the partition is a palindrome.

Return all possible palindrome partitioning of s.

For example, given s = "aab",
Return

  [
    ["aa","b"],
    ["a","a","b"]
  ]

给定一个字符串,分隔字符,使其中每一组字符都是回文字符,返回所有可能的情况。

分析:利用回溯法进行分析,可以从第一个字符开始

List<List<String>> res = new  ArrayList<List<String>>();
		public List<List<String>> partition(String s) {
			if(s.length() == 0 || s == null)
				return res;
			backtrack(s, new ArrayList<String>(), 0);
			return res;
	    }
		
		public void backtrack(String s, List<String> list, int index){
			if(index == s.length())
			{
				res.add(new ArrayList<String>(list));
				return;
			}
			for(int i = index + 1; i <= s.length(); i++)
			{
				if(isPalindrome(s.substring(index,i)))
				{
					list.add(s.substring(index,i));
					backtrack(s, list, i);
					list.remove(list.size() - 1);
				}
			}
		}
		
		public boolean isPalindrome(String s){
			if(s.length() == 0 || s == null)
				return false;
			int left =0, right = s.length() - 1;
			while(left<right)
			{
				if(s.charAt(left) == s.charAt(right))
				{
					left++;
					right--;
				}else
					return false;
			}
			return true;
		}


ZigZag Conversion(循环对角线结构)

The string "PAYPALISHIRING" is written in a zigzag pattern on a given number of rows like this: (you may want to display this pattern in a fixed font for better legibility)

P   A   H   N
A P L S I I G
Y   I   R
And then read line by line:  "PAHNAPLSIIGYIR"

Write the code that will take a string and make this conversion given a number of rows:

string convert(string text, int nRows);

convert("PAYPALISHIRING", 3) should return "PAHNAPLSIIGYIR".

翻译:一个字符串用给定的行数用循环对角线结构的形式表示,则变成如下:(你可以以一个更易读的方式展示)

分析:

这就是循环对角线结构,可以以一列多一列少来作为判断的依据,首先,定义一个StringBuffer数组来存储每一行的值,根据输入的值为nRows,则列的数量多为flagLong=nRows,列的数量少的为flagShort=nRows-2,则每次进入一行多的就加入对应的string里,需要注意的一点事关于补空格的问题,因为我是用i%nRows去

算出他的对应数组的序号,所以要补空格才能得出对应的序号。那么每次按照这样的点来取,最后数组里面就存放了循环对角线每一行的值。

代码:

public String convert(String s, int numRows) {
			if(s == null || s.length() == 0 || numRows == 0)
				return "";
			if(numRows == 1 || s.length() <= numRows)
				return s;
	        StringBuffer[] array = new StringBuffer[numRows];
	        int temp = 0;//对应序号
	        int flagLong = numRows;
	        int flagShort = numRows - 2;
	        int add = 0;
	        for(int i = 0; i < s.length(); i++)
	        {
	        	temp = i % numRows;
	        	if(flagLong != 0)
	        	{
	        		flagLong--;
		        	temp = (i + add) % numRows;//补空
	        		flagShort = (flagLong == 0)?(numRows - 2):0;
	        		add = (flagLong == 0)?(add + 2):add;
	        	}else if(flagShort != 0){
		        	temp = flagShort ;
	        		flagShort--;
	        		flagLong = (flagShort == 0)?numRows:0;
	        	}
	        	if(array[temp] == null)
	        	{
	        		array[temp] = new StringBuffer();
	        	}
        		array[temp].append(s.charAt(i));
	        }
			for(int i = 1; i < numRows; i++)
				array[0].append(array[i]);//合并数据
			return array[0].toString();
	    }



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值