给出一个 32 位的有符号整数,你需要将这个整数中每位上的数字进行反转。
假设我们的环境只能存储得下 32 位的有符号整数,则其数值范围为 [−231, 231 − 1]。请根据这个假设,如果反转后整数溢出那么就返回 0。
class Solution {
public int reverse(int x) {
//拿到几位数n,然后拿出来一个尾巴,跟n计算一下。
//需要考虑正负,最后一位是0
//处理正负
boolean isLowerThanZero = false;
if (x<0) {
isLowerThanZero = true;
x = -x;
}
//用栈来存放数据
Stack stack = new Stack();
while(x != 0){
stack.push(x%10);
x = x/10;
}
//下面这段代码是从栈里拿出来数据组装成想要的样子 123 -》 321
int result = 0;
int tenTimes = 1;
while(!stack.empty()){
result = result + (int)stack.pop()*tenTimes;
tenTimes *= 10;
}
//考虑整数溢出的情况,这部分代码有问题一直没调出来
int max = (2<<31) -1 ;
if(result > 2147483647){
return 0;
}
//如果是负数还原
if(isLowerThanZero){
result = -result;
}
return result;
}
}
废了很多功夫,最终没做出来。指数运算与溢出的处理,超出了脑容量了。处理的不是很好。做的过程中很努力的在避开循环了,但是还是做的不好。
class Solution {
public int reverse(int x) {
int rev = 0;
while (x != 0) {
int pop = x % 10;
x /= 10;
if (rev > Integer.MAX_VALUE/10 || (rev == Integer.MAX_VALUE / 10 && pop > 7)) return 0;
if (rev < Integer.MIN_VALUE/10 || (rev == Integer.MIN_VALUE / 10 && pop < -8)) return 0;
rev = rev * 10 + pop;
}
return rev;
}
}
判断一个整数是否是回文数。回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数。
回文数无非就是头尾对应位置的数是一样的,就想着转化为字符串去匹配。
过程中需要注意,字符串最后一个是str.length()-1。跟数组一样,到不了length,是从0开始的。
class Solution {
public boolean isPalindrome(int x) {
//转换成字符串
String str = x + "";
boolean result = true;
for (int i = 0; i < str.length()/2; i++) {
if(str.charAt(i) != str.charAt(str.length()-1-i)){
result = false;
}
}
return result;
}
}
public class Solution {
public bool IsPalindrome(int x) {
// 特殊情况:
// 如上所述,当 x < 0 时,x 不是回文数。
// 同样地,如果数字的最后一位是 0,为了使该数字为回文,
// 则其第一位数字也应该是 0
// 只有 0 满足这一属性
if(x < 0 || (x % 10 == 0 && x != 0)) {
return false;
}
int revertedNumber = 0;
while(x > revertedNumber) {
revertedNumber = revertedNumber * 10 + x % 10;
x /= 10;
}
// 当数字长度为奇数时,我们可以通过 revertedNumber/10 去除处于中位的数字。
// 例如,当输入为 12321 时,在 while 循环的末尾我们可以得到 x = 12,revertedNumber = 123,
// 由于处于中位的数字不影响回文(它总是与自己相等),所以我们可以简单地将其去除。
return x == revertedNumber || x == revertedNumber/10;
}
}
先建立一个罗马数字与数值对应的字典,然后一个一个字符解析之后累加。
针对特殊处理的字符,确定之后,用负数的形式进行特殊的负数累加。
我认为这个思路没什么问题,但是sign那一行报空指针。最后原因是我初始化字典的时候,错用了双引号。
最终也可以成功提交。
// 先把字典装进map里面
Map<Character,Integer> map = new HashMap<>();
//1
map.put('I',1);
map.put('V',5);
map.put('X',10);
map.put('L',50);
map.put('C',100);
map.put('D',500);
map.put('M',1000);
// 符号
int result = 0;
for (int i = 0; i < s.length()-1; i++) {
int sign = 1;
if ((s.charAt(i)=='I' ||s.charAt(i)=='X' ||s.charAt(i)=='C') ) {
if(map.get(s.charAt(i))*5 ==map.get(s.charAt(i+1)) ||
map.get(s.charAt(i))*10 ==map.get(s.charAt(i+1))){
sign = -1;
}
}
result+= sign* map.get(s.charAt(i));
}
result+= map.get(s.charAt(s.length()-1));
return result;
}
class Solution {
public int romanToInt(String s) {
Map<String, Integer> map = new HashMap<>();
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);
int ans = 0;
for(int i = 0;i < s.length();) {
if(i + 1 < s.length() && map.containsKey(s.substring(i, i+2))) {
ans += map.get(s.substring(i, i+2));
i += 2;
} else {
ans += map.get(s.substring(i, i+1));
i ++;
}
}
return ans;
}
}
解析里面的做法是在哈希表里面增加一个字符与2个字符。然后利用字符串切割并匹配的思路。
根据用的字符的数量移动游标i,控制一步还是两步。
这个解法比我想的要更奇妙。
hashmap可以换成switch,可能效率更快。
class Solution {
public String longestCommonPrefix(String[] strs) {
if(strs.length == 0){
return "";
}
//1.比较长度 选最小的长度 作为循环的n 拿出来去比
int minLengthIndex = 0;
for (int i = 1; i < strs.length; i++) {
if (strs[i].length()< strs[minLengthIndex].length()) {
minLengthIndex = i;
}
}
String CommonPrefix = "";
for (int i = 0; i < strs[minLengthIndex].length() ; i ++) {
boolean isAdd = true;
for (int j = 0; j < strs.length; j++) {
if (strs[j].charAt(i)!=strs[minLengthIndex].charAt(i)) {
isAdd = false;
break;
}
}
if(isAdd){
CommonPrefix = CommonPrefix + strs[minLengthIndex].charAt(i);
}else {
break;
}
}
return CommonPrefix;
}
}
上来判断一下特殊情况,空数组。
然后找出最短长度的数组中的元素,作为字符游标移动的母串。
以最短的那个为目标,对比每一个的每一位,看是不是一样。
思路很简单,但是部分测试用例。没有通过。
后来ide打断点,我对后面匹配的数据没有做处理,加了isAdd的else判断之后就能通过了。
这个题,解析有好多。
给定一个只包括 ‘(’,’)’,’{’,’}’,’[’,’]’ 的字符串,判断字符串是否有效。
有效字符串需满足:
左括号必须用相同类型的右括号闭合。
左括号必须以正确的顺序闭合。
注意空字符串可被认为是有效字符串。
首先想到的就是栈的思想,加一个哈希表做检索匹配。但是代码最终失败了。
class Solution {
public boolean isValid(String s) {
//第一想到的就是栈
Stack stack = new Stack();
boolean result = true;
Map<String,String> map = new HashMap<>();
map.put(")","(");
map.put("}","{");
map.put("]","[");
while(s.equals("")){
Character tmp = s.charAt(0);
if (map.containsKey(tmp+"")) {
String returnChar = (String)stack.pop();
if (!returnChar.equals(map.get(tmp+""))) {
result = false;
}
}else{
stack.push(tmp+"");
}
s = s.substring(1);
}
if(!stack.empty()){
result = false;
}
return result;
}
}
总的来说,我用栈这种数据结构的思想是对的。
跟我的实现方式也差不多。但是我的代码为啥有问题,一直没发现。
class Solution {
// Hash table that takes care of the mappings.
private HashMap<Character, Character> mappings;
// Initialize hash map with mappings. This simply makes the code easier to read.
public Solution() {
this.mappings = new HashMap<Character, Character>();
this.mappings.put(')', '(');
this.mappings.put('}', '{');
this.mappings.put(']', '[');
}
public boolean isValid(String s) {
// Initialize a stack to be used in the algorithm.
Stack<Character> stack = new Stack<Character>();
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
// If the current character is a closing bracket.
if (this.mappings.containsKey(c)) {
// Get the top element of the stack. If the stack is empty, set a dummy value of '#'
char topElement = stack.empty() ? '#' : stack.pop();
// If the mapping for this bracket doesn't match the stack's top element, return false.
if (topElement != this.mappings.get(c)) {
return false;
}
} else {
// If it was an opening bracket, push to the stack.
stack.push(c);
}
}
// If the stack still contains elements, then it is an invalid expression.
return stack.isEmpty();
}
}
到这里,我不再强刷算法了,回过头了,重新看一遍java的数据结构,对东西建立起来体系再回来!