Java版:
1.两数之和:hash表法:key:value = nums[i]:i
hash有对应差值,得到结果,否则添加到hash中
class Solution {
public int[] twoSum(int[] nums, int target) {
Map<Integer,Integer> hasd = new HashMap<>();
for(int i=0;i<nums.length;i++){
if(hasd.containsKey(target-nums[i])){
return new int[]{i, hasd.get(target-nums[i])};
}
hasd.put(nums[i],i);
}
return null;
}
}
2.整数反转:
判断是否溢出a>Integer.MAX_VALUE/10 || (a==Integer.MAX_VALUE/10 && pop > 7和a<Integer.MIN_VALUE/10 || (a==Integer.MIN_VALUE/10 && pop <-8)
不溢出,则通过取余数获得尾数,再更新
class Solution {
public int reverse(int x) {
int a = 0;
while(x != 0){
int pop = x%10;
if(a>Integer.MAX_VALUE/10 || (a==Integer.MAX_VALUE/10 && pop > 7)){
return 0;
}
if(a<Integer.MIN_VALUE/10 || (a==Integer.MIN_VALUE/10 && pop <-8)){
return 0;
}
a=a*10+pop;
x=x/10;
}
return a;
}
}
3.回文数:
关键:如何判断反转了一半:我们将原始数字除以 10,然后给反转后的数字乘上 10,所以,当原始数字小于反转后的数字时,就意味着我们已经处理了一半位数的数字。
对10取余获得尾数,除10去掉个位数。
10的整数要提前判断
class Solution {
public boolean isPalindrome(int x) {
if(x < 0 || (x % 10 == 0 &&x!=0)) return false;
int a=0;
while(x>a){
a = a*10 + x%10;
x = x/10;
}
return x == a || x == a/10;
}
}
罗马数字:大数在小数左边,小数在大数右边取负
int num = 0;
if (a.length() == 0) return 0;
Character[] code1 = new Character[]{'I', 'V', 'X', 'L','C', 'D', 'M'};
Integer[] code2 = new Integer[]{1, 5, 10, 50, 100, 500, 1000};
Map<Character , Integer> code = new HashMap<>();
for(int i = 0; i<code1.length; i++){
code.put(code1[i], code2[i]);
}
int preNum = code.get(a.charAt(0)).intValue();
for (int i =1; i< a.length(); i++){
if (preNum < code.get(a.charAt(i)).intValue()){
preNum = -preNum;
}
num = num+preNum;
preNum=code.get(a.charAt(i)).intValue();
}
num = num+preNum;
return num;
括号匹配:主要使用栈进行判断
public boolean isValid(String s) {
Stack<Character> stack = new Stack();
for (int i = 0; i<s.length();i++){
if (s.charAt(i) == '(' || s.charAt(i) == '{' ||s.charAt(i) == '[') {
stack.push(s.charAt(i));
}else {
if (stack.empty()) return false;
if (s.charAt(i) == ')' ){
if (stack.peek().charValue()== '('){
stack.pop();continue;
}else {
return false;
}
}
if (s.charAt(i) == ']' ){
if (stack.peek().charValue()== '['){
stack.pop();continue;
}else {
return false;
}
}
if (s.charAt(i) == '}' ){
if (stack.peek().charValue()== '{'){
stack.pop();continue;
}else {
return false;
}
}
}
}
return stack.empty();
}
合并有序列表:创建一个头指针用于返回,在创建一个用于插入操作,注意断链。
ListNode head = new ListNode(-1);
ListNode p = head;
while (l1!=null && l2!=null){
if (l1.val <= l2.val){
p.next = l1;
l1 = l1.next;
p = p.next;
}else {
p.next = l2;
l2 = l2.next;
p = p.next;
}
}
while (l1!=null){
p.next = l1;
l1 = l1.next;
p = p.next;
}
while (l2!=null){
p.next = l2;
l2 = l2.next;
p = p.next;
}
head = head.next;
return head;
删除排序数组重复项:维护2个指针,一个快指针,一个慢指针,快指针用于取项,慢指针用于更新
int i=0,j=0;
for(;j<nums.length;j++){
if (nums[i] == nums[j]){
continue;
}else {
i = i+1;
nums[i] = nums[j];
}
}
return i+1;
移除元素:同样维护2个指针
public int removeElement(int[] nums, int val) {
int i=0, j =0;
for (;j<nums.length;){
if (nums[j] == val){
j++;
continue;
}
if (nums[j] != val){
nums[i] = nums[j];
j++;
i++;
continue;
}
}
return i;
}
搜索插入位置:双指针法
if (nums[0] <= target) return 0;
int i = 0;
for (int j =1;j<nums.length;j++){
if (nums[i]<target && nums[j]>=target){
return j;
}else {
i++;
}
}
return nums.length;