1.给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。
class Solution {
public int[] twoSum(int[] nums, int target) {
for (int i = 0; i <nums.length ; i++){
for(int j=i+1; j<nums.length ; j++){
if(target-nums[i]==nums[j]){
return new int[] {i,j};
}
}
}
throw new IllegalArgumentException("no two sum solution");
}
}
暴力破解: 注意事项:1. return new int[] {i,j}; 应该是一个数组的形式。 最后如果失败应该是 throw new IllegalArgumentException(“no two sum solution”); 表明向方法传递了一个不合法或不正确的参数
map集合总结:
1.是一个双列集合,(一个key ,一个value)
2. key 和value 的数据结构可以相同也可以不同。
3. key 不允许重复,value 可以重复。
HashMap
1.无序的集合
4. LinkHashMap
class Solution {
public int[] twoSum(int[] nums, int target) {
Map<Integer,Integer> map = new HashMap();
for(int i=0; i< nums.length ; i++){
int complemnt = target - nums[i];
if(map.containsKey(complemnt)){
return new int[] {map.get(complemnt),i};
}
map.put(nums[i],i);
}
throw new IllegalArgumentException("no two sum solution");
}
}
最简单的解题方式: 在往map里面装的时候,就要判断 Map 里面有没有符合的数。
注意:
2.给出两个 非空 的链表用来表示两个非负的整数。其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字。
如果,我们将这两个数相加起来,则会返回一个新的链表来表示它们的和。
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
ListNode l3 = new ListNode(0);
ListNode p1 = l1, p2 = l2, p3 = l3;
int carry =0;
while(p1 != null || p2 != null){
int x = (p1 != null)? p1.val:0;
int y = (p2 != null)?p2.val:0;
int sum = carry+x+y;
carry = sum /10;
p3.next= new ListNode(sum%10);
p3=p3.next;
if(p1!=null) p1=p1.next;
if(p2!=null) p2=p2.next;
}
if(carry>0){
p3.next = new ListNode(carry);
}
return l3.next;
}
}
解题: 建立一个链表,和C语言的指针是一样的。其中的关键最后return l3.next; 因为在刚建立的时候的节点是0 ,所有返回的时候要变成next;
**3.**给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。
示例 1:
输入: “abcabcbb”
输出: 3
解释: 因为无重复字符的最长子串是 “abc”,所以其长度为 3。
class Solution {
public int lengthOfLongestSubstring(String s) {
int n = s.length(), ans = 0;
Map<Character, Integer> map = new HashMap<>();
for (int end = 0, start = 0; end < n; end++) {
char alpha = s.charAt(end);
if (map.containsKey(alpha)) {
start = Math.max(map.get(alpha), start);
}
ans = Math.max(ans, end - start + 1);
map.put(s.charAt(end), end + 1);
}
return ans;
}
}
注意事项:1. Map
2.其中加入了散列表,和滑动窗口。
3.值得注意的是:其中的ans 只要记录最大的就可以、
4.start = Math.max(map.get(alpha), start); 是找到了start 以前的也不会改变start.
4.给定两个大小为 m 和 n 的正序(从小到大)数组 nums1 和 nums2。
请你找出这两个正序数组的中位数,并且要求算法的时间复杂度为 O(log(m + n))。
你可以假设 nums1 和 nums2 不会同时为空。
class Solution {
public double findMedianSortedArrays(int[] nums1, int[] nums2) {
if(nums1==null||nums1.length==0){
int length = nums2.length;
int middle = length / 2;
if(length % 2 != 0){
return nums2[middle];
}else{
return (nums2[middle]+nums2[middle-1])/2.0;
}
}
if(nums2==null||nums2.length==0){
int length = nums1.length;
int middle = length/2;
if(length % 2 != 0){
return nums1[middle];
}else{
return (nums1[middle]+nums1[middle-1])/2.0;
}
}
int i1 = 0;
int i2 = 0;
int last =0;
int current=0;
int l1 = nums1.length;
int l2 = nums2.length;
int sum = l1+l2;
int middle = sum /2;
int index =0;
while(index <= middle){
index++;
last = current;
if (i2 == l2) {
current = nums1[i1];
i1++;
continue;
}
if (i1 == l1) {
current = nums2[i2];
i2++;
continue;
}
if (nums1[i1]<=nums2[i2]){
current = nums1[i1];
i1++;
}else{
current = nums2[i2];
i2++;
}
}
if(sum%2==0){
return (last+current)/2.0;
}else{
return current;
}
}
}
本次的代码是按着自己的思路写出来的,应该坚持自己的思路来写,而不是看别人的代码,思路也是非常的简单,就是参数非常 的多,但是是符合题目要求的。
5 给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为 1000。
示例 1:
输入: “babad”
输出: “bab”
注意: “aba” 也是一个有效答案。
class Solution {
public String longestPalindrome(String s) {
int len = s.length();
if(len<2){
return s;
}
int maxLen = 1;
String res = s.substring(0,1);
for(int i =0; i<len-1; i++){
for(int j=i+1;j<len ;j++){
if(j-i+1>maxLen&& huiwen(s,i,j)){
maxLen=j-i+1;
res = s.substring(i,j+1);
}
}
}
return res;
}
private boolean huiwen(String s, int left,int right){
while(left<right){
if(s.charAt(left) != s.charAt(right)){
return false;
}
left++;
right--;
}
return true;
}
}
此方法是暴力破解方法,运用了两个for 循环,第一个for指定起始位置,第二个for 是指定了substring 的范围,然后写一个方法,调用huiwen 方法,回文方法是从两端开始,进行对比,如果对比不对,就会返回false. 这是暴力破解的方法。
**易错点:**if(s.charAt(left) != s.charAt(right))
暴力法采用双指针两边夹,验证是否是回文子串。
第二种方法:: 动态规划:
class Solution {
public String longestPalindrome(String s) {
int len = s.length();
if(len < 2 ){
return s;
}
int currlen=0;
int start=0;
int maxlen=1;
Boolean[][] dp = new Boolean[len][len];
for(int i =0; i<len ;i++){
dp[i][i]=true;
}
for( int j=1; j<len ; j++){
for(int i=0; i<j; i++){
if(s.charAt(i)==s.charAt(j)){
if(j-i<3){
dp[i][j]=true;
}else{
dp[i][j]=dp[i+1][j-1];
}
}else{
dp[i][j]=false;
}
if(dp[i][j]){
currlen = j-i+1;
if(currlen>maxlen){
start=i;
maxlen = currlen;
}
}
}
}
return s.substring(start, start+maxlen);
}
}
注意事项;动态规划就是建表,j 和 i 相当于圈定了范围,然后就是在重复上一次的执行过程,过程是自底向下的,然后在一次的比较就可以。
6. 将一个给定字符串根据给定的行数,以从上往下、从左到右进行 Z 字形排列。
比如输入字符串为 “LEETCODEISHIRING” 行数为 3 时,排列如下:
L C I R
E T O E S I I G
E D H N
之后,你的输出需要从左往右逐行读取,产生出一个新的字符串,比如:“LCIRETOESIIGEDHN”。
请你实现这个将字符串进行指定行数变换的函数:
string convert(string s, int numRows);
示例 1:
输入: s = “LEETCODEISHIRING”, numRows = 3
输出: “LCIRETOESIIGEDHN”
示例 2:
输入: s = “LEETCODEISHIRING”, numRows = 4
输出: “LDREOEIIECIHNTSG”
解释:
L D R
E O E I I
E C I H N
T S G
class Solution {
public String convert(String s, int numRows) {
if(numRows<2){
return s;
}
List<StringBuilder> rows = new ArrayList<StringBuilder>();
for(int i =0; i<numRows; i++)rows.add(new StringBuilder());
int i=0;
int flag=-1;
for(char c :s.toCharArray()){
rows.get(i).append(c);
if(i==0||i==numRows-1) flag= -flag;
i+=flag;
}
StringBuilder res = new StringBuilder();
for(StringBuilder row: rows)res.append(row);
return res.toString();
}
}
注意事项: 这个flag 用的太秀了,就像可以 摆动的旗子,可以进行来回的摆动,并且在ArrayList 里面建立的字符串数组,真的是很强,字符串数组的编号等。其实写程序的过程也是在往数据里面写的过程。
7.
给出一个 32 位的有符号整数,你需要将这个整数中每位上的数字进行反转。
示例 1:
输入: 123
输出: 321
class Solution {
public int reverse(int x) {
long n=0;
while(x !=0){
n= n*10+x%10;
x = x/10;
}
return (int)n==n? (int)n:0;
}
}
最简单的数字的翻转。
常见知识点:
s.toCharArray() 将字符串转换为字符数组
第二种解法:
class Solution {
public int reverse(int x) {
String a = Integer.toString(x);
int b=1;
if(a.charAt(0) == '-') {
a = a.substring(1);
b = -1;
}
char[] chars = a.toCharArray();
char[] chars1 = new char[chars.length];
for (int i = chars.length - 1; i >= 0; i--) {
chars1[chars.length - 1 - i] = chars[i];
}
Long along = Long.valueOf(new String(chars1));
if(along>Integer.MAX_VALUE||along<Integer.MIN_VALUE){
return 0;
}
return (int)(along*b);
}
}
其中最重要的是里面的对,字符转换为字符串, 在由字符串转换为数字的过程。
String a = Integer.toString(x); //把数字转换为字符串
a.charAt(0) == ‘-’ // 字符串可以拿出任意位置的字符
char[] chars = a.toCharArray(); // 转换为字符串数组
Long along = Long.valueOf(new String(chars1)); //先建立字符串,然后转化为long 值。
其中 long string array 三者的转换的中间量是string