1,罗马数字转十进制
描述:
罗马数字包含以下七种字符: I
, V
, X
, L
,C
,D
和 M
。
字符 数值
I 1
V 5
X 10
L 50
C 100
D 500
M 1000
例如,
-
罗马数字 2 写做 II ,即为两个并列的 1。
-
12 写做 XII ,即为 X + II 。 27 写做 XXVII, 即为 XX + V + II 。
通常情况下,罗马数字中小的数字在大的数字的右边。但也存在特例,例如 4 不写做 IIII,而是 IV。数字 1 在数字 5 的左边,所表示的数等于大数 5 减小数 1 得到的数值 4 。同样地,数字 9 表示为 IX。这个特殊的规则只适用于以下六种情况:
-
I 可以放在 V (5) 和 X (10) 的左边,来表示 4 和 9。
-
X 可以放在 L (50) 和 C (100) 的左边,来表示 40 和 90。
-
C 可以放在 D (500) 和 M (1000) 的左边,来表示 400 和 900。
给定一个罗马数字,将其转换成整数。输入确保在 1 到 3999 的范围内。
示例 1:
输入: "III"
输出: 3
示例 2:
输入: "IV"
输出: 4
示例 3:
输入: "IX"
输出: 9
示例 4:
输入: "LVIII"
输出: 58
解释: L = 50, V= 5, III = 3.
示例 5:
输入: "MCMXCIV"
输出: 1994
解释: M = 1000, CM = 900, XC = 90, IV = 4.
leedcode 13
解答:
public class LeedCode13 {
private static HashMap<Character,Integer> map = new HashMap<>();
static {
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);
}
public static void main(String[] args) {
System.out.println(romanToInt("III"));//3
System.out.println(romanToInt("IV"));//4
System.out.println(romanToInt("IX"));//9
System.out.println(romanToInt("LVIII"));//58
System.out.println(romanToInt("MCMXCIV"));//1994
}
public static int romanToInt(String s) {
int result = 0;
int a = 0;
int i = 0;
for( ; i < s.length() - 1; i ++){
a = map.get(s.charAt(i));
if(a < map.get(s.charAt(i + 1))){
result -= a;
}else {
result += a;
}
}
result += map.get(s.charAt(i));
return result;
}
}
2,输出target的值
输入一个递增排序的数组nums和一个数字target (数组nums中的数字和target的数值均为整数),在数组中查找两个数,使得它们的差正好是target。如果有多对数字的和等于target,输出全部组合。
要求: 要考虑时间复杂度和空间复杂度
如果数组中不存在目标值,返回 [-1, -1]。
示例 1:
输入:nums = [1,2,4,7,8,11,15], target = 15
输出: [4,11], [7,8]
示例 2:
输入: nums = [5,7,9,10,13], target = 7
输出: [-1,-1]
解答:
//时间复杂度为O(n)
public class Test {
public static void main(String[] args) {
int array1[] = { 1, 2, 4, 7, 8, 11, 15 };
int array2[] = { 5,7,9,10,13 };
function(array1,15);
function(array2,7);
}
public static void function(int[] data,int sum){
boolean flag = true;
int left = 0;
int right = data.length -1;
while(left <= right){
if(data[left] + data[right] == sum){
flag = false;
System.out.print("["+data[left] + "," + data[right]+"] ");
left --;
right --;
continue;
}else if(data[left] + data[right] >sum)
right --;
else
left ++;
}
if(flag){
System.out.print("[-1,-1]");
}
System.out.println();
}
}
3,判断链表是否为回文结构
给定一个单链表(无环),请判断是否是回文结构。在删除倒数第K个节点后,是否为回文结构。(回文结构:从头到尾遍历节点的值序列结果,与从尾到头遍历的值序列结果是一样的)
要求: 要考虑时间复杂度和空间复杂度
示例 1:
输入: 1->8->4->4->8->1, K=3
输出: true, true
示例 2:
输入: 1->2->5->2->1, K=2
输出: true, false
示例 3:
输入: 1->2->5->3->2->1, K=3
输出: false, true
解答:
public class Test2 {
//经过分析,平行的遍历链表2次,2次都是遍历一半,时间复杂度为 O(n)。占用的空间为链表长度的一半,空间复杂度为O(n)
public static void main(String[] args) {
int[] temp1 = {1,8,4,4,8,1};
Node head1 = init(temp1);
isPalindrome(head1,3);
int[] temp2 = {1,2,5,2,1};
Node head2 = init(temp2);
isPalindrome(head2,2);
int[] temp3 = {1,2,5,3,2,1};
Node head3 = init(temp3);
isPalindrome(head3,3);
}
public static class Node {//不带头节点
public int value;
public Node next;
public Node(int data) {
this.value = data;
}
}
public static void isPalindrome(Node head, int k) {
boolean a = isPalindrome(head);
Node p = head;
delete(head,k);
boolean b = isPalindrome(head);
System.out.println(a + " " + b);
}
//初始化一个链表
public static Node init(int[] values){
if(values != null &&values.length > 0){
Node head = new Node(values[0]);
Node p = head;
for(int i = 1; i < values.length ; i ++){
p.next = new Node(values[i]);
p = p.next;
}
return head;
}
return null;
}
//删除第k个节点,按照示例的意思,应该是从1开始
public static void delete(Node head, int k) {
if (k < 1) return;
if (k == 1) {
if(head.next != null){
head = head.next;
}
}else {
Node front = null;
Node p = head;
for(int i = 1; i < k && p.next != null; i ++, p = p.next){
front = p;
}
front.next = p.next;
}
}
//使用快慢指针
public static boolean isPalindrome(Node head) {
if (head == null || head.next == null) return true;
//这样可以确保慢速的指针肯定在中间,或中间偏右。可以画图
Node low = head.next; //慢指针
Node fast = head;//快指针
while (fast.next != null && fast.next.next != null) {
low = low.next;
fast = fast.next.next;
}
Stack<Node> stack = new Stack<Node>();
while (low != null) {
stack.push(low);
low = low.next;
}
Node p = head;
while (!stack.isEmpty()) {
if (p.value != stack.pop().value) {
return false;
}
p = p.next;
}
return true;
}
}
4,leedcode7
给出一个 32 位的有符号整数,你需要将这个整数中每位上的数字进行反转。
示例 1:
输入: 123
输出: 321
示例 2:
输入: -123
输出: -321
示例 3:
输入: 120
输出: 21
注意:
假设我们的环境只能存储得下 32 位的有符号整数,则其数值范围为 [−2^31, 2^31 − 1]。请根据这个假设,如果反转后整数溢出那么就返回 0。
解题:
public class Leedcode7 {
public static int MAX_VALUE = Integer.MAX_VALUE;
public static int MIN_VALUE = Integer.MIN_VALUE;
//占用内存或耗时较多
public static int reverse(int x) {
String data = x + "";
String res = "";
int min = x >= 0 ? 0 : 1;
for (int i = data.length() - 1; i >= min; i--) {
res += data.charAt(i);
}
long a = Long.parseLong(res);
if (x < 0)
a *= -1;
if (a > MAX_VALUE || a < MIN_VALUE)
return 0;
return (int) a;
}
//评论区解法算法
public static int reverse1(int x) {
long res = 0;
while(x != 0) {
res = res * 10 + x % 10;
x /= 10;
}
return (int)res == res ? (int)res : 0;
}
}
5,leedcode15
给定一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?找出所有满足条件且不重复的三元组。
注意:答案中不可以包含重复的三元组。
示例:
给定数组 nums = [-1, 0, 1, 2, -1, -4],
满足要求的三元组集合为:
[
[-1, 0, 1],
[-1, -1, 2]
]
解法:
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class Leedcode15 {
public static void main(String[] args) {
System.out.println(Arrays.asList(1,2,3).equals(Arrays.asList(3,2,1)));
}
//这种解法超时 自己想的解法
public static List<List<Integer>> threeSum(int[] nums) {
List<List<Integer>> res = new ArrayList<>();
for(int i = 0; i < nums.length;i ++) {
for(int j = i + 1; j < nums.length; j ++) {
for(int k = j + 1; k < nums.length; k ++) {
if(nums[i] + nums[j] + nums[k] == 0) {
add(res,Arrays.asList(nums[i],nums[j],nums[k]));
}
}
}
}
return res;
}
private static void add(List<List<Integer>> res, List<Integer> asList) {
System.out.println(asList);
boolean flag = true;
for(List<Integer> list : res) {
if(list.containsAll(asList) && asList.containsAll(list)) {
flag = false;
break;
}
}
if(flag)
res.add(asList);
}
//评论区解法
public static List<List<Integer>> threeSum1(int[] nums){
List<List<Integer>> res = new ArrayList<>();
Arrays.sort(nums);
for(int i = 0; i < nums.length - 2; i ++) {
if(i == 0 || nums[i] != nums[i - 1]) {
int wantedNum = 0 - nums[i]; //想要的另外两个值
int left = i + 1;
int right = nums.length - 1;
while(left < right) {
if(nums[left] + nums[right] == wantedNum) {
res.add(Arrays.asList(nums[i],nums[left],nums[right]));
while(left < right && nums[left] == nums[left + 1]) left ++;
while(left < right && nums[right] == nums[right - 1]) right --;
left ++;
right --;
}else if(nums[left] + nums[right] > wantedNum){
while(left < right && nums[right] == nums[right - 1]) right --;
right --;
}else if(nums[left] + nums[right] < wantedNum) {
while(left < right && nums[left] == nums[left + 1]) left ++;
left ++;
}
}
}
}
return res;
}
}
6,leedcode3
给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。
示例 1:
输入: "abcabcbb"
输出: 3
解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。
示例 2:
输入: "bbbbb"
输出: 1
解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。
示例 3:
输入: "pwwkew"
输出: 3
解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。
请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。
解答:
public class leedcode3 {
public static void main(String[] args) {
System.out.println(lengthOfLongestSubstring("abcabcbb"));//3
System.out.println(lengthOfLongestSubstring("bbbbb"));//1
System.out.println(lengthOfLongestSubstring("pwwkew"));//3
System.out.println(lengthOfLongestSubstring("aab"));//2
System.out.println(lengthOfLongestSubstring("dvdf"));//3
}
public static int lengthOfLongestSubstring(String s) {
StringBuffer cap = new StringBuffer();//cap的作用是收集,不重子串
List<Integer> weights = new ArrayList<>();
for(int i = 0; i < s.length(); i ++) {
String temp = cap.toString();
int index = temp.indexOf(s.charAt(i) + "");
if(index != -1) { //发现了重复
weights.add(cap.length());//发现了重复 ,将当前不重复字串的长度记录以下
cap.setLength(0);//清空cap
cap.append(temp.substring(index + 1));//将从字串重复的位置阶段,后面是不重复的字串
cap.append(s.charAt(i));
}else {
cap.append(s.charAt(i));
}
}
weights.add(cap.length());
weights.sort(new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o2 - o1;
}
});
return weights.get(0);
}
}